• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/media/IR/
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 *  You should have received a copy of the GNU General Public License
17 *  along with this program; if not, write to the Free Software
18 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/kernel.h>
24#include <linux/sched.h>
25#include <linux/errno.h>
26#include <linux/ioctl.h>
27#include <linux/fs.h>
28#include <linux/poll.h>
29#include <linux/completion.h>
30#include <linux/errno.h>
31#include <linux/mutex.h>
32#include <linux/wait.h>
33#include <linux/unistd.h>
34#include <linux/kthread.h>
35#include <linux/bitops.h>
36#include <linux/device.h>
37#include <linux/cdev.h>
38
39#include <media/lirc.h>
40#include <media/lirc_dev.h>
41
42static int debug;
43
44#define IRCTL_DEV_NAME	"BaseRemoteCtl"
45#define NOPLUG		-1
46#define LOGHEAD		"lirc_dev (%s[%d]): "
47
48static dev_t lirc_base_dev;
49
50struct irctl {
51	struct lirc_driver d;
52	int attached;
53	int open;
54
55	struct mutex irctl_lock;
56	struct lirc_buffer *buf;
57	unsigned int chunk_size;
58
59	struct task_struct *task;
60	long jiffies_to_wait;
61
62	struct cdev cdev;
63};
64
65static DEFINE_MUTEX(lirc_dev_lock);
66
67static struct irctl *irctls[MAX_IRCTL_DEVICES];
68
69/* Only used for sysfs but defined to void otherwise */
70static struct class *lirc_class;
71
72/*  helper function
73 *  initializes the irctl structure
74 */
75static void init_irctl(struct irctl *ir)
76{
77	dev_dbg(ir->d.dev, LOGHEAD "initializing irctl\n",
78		ir->d.name, ir->d.minor);
79	mutex_init(&ir->irctl_lock);
80	ir->d.minor = NOPLUG;
81}
82
83static void cleanup(struct irctl *ir)
84{
85	dev_dbg(ir->d.dev, LOGHEAD "cleaning up\n", ir->d.name, ir->d.minor);
86
87	device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor));
88
89	if (ir->buf != ir->d.rbuf) {
90		lirc_buffer_free(ir->buf);
91		kfree(ir->buf);
92	}
93	ir->buf = NULL;
94}
95
96/*  helper function
97 *  reads key codes from driver and puts them into buffer
98 *  returns 0 on success
99 */
100static int add_to_buf(struct irctl *ir)
101{
102	if (ir->d.add_to_buf) {
103		int res = -ENODATA;
104		int got_data = 0;
105
106		/*
107		 * service the device as long as it is returning
108		 * data and we have space
109		 */
110get_data:
111		res = ir->d.add_to_buf(ir->d.data, ir->buf);
112		if (res == 0) {
113			got_data++;
114			goto get_data;
115		}
116
117		if (res == -ENODEV)
118			kthread_stop(ir->task);
119
120		return got_data ? 0 : res;
121	}
122
123	return 0;
124}
125
126/* main function of the polling thread
127 */
128static int lirc_thread(void *irctl)
129{
130	struct irctl *ir = irctl;
131
132	dev_dbg(ir->d.dev, LOGHEAD "poll thread started\n",
133		ir->d.name, ir->d.minor);
134
135	do {
136		if (ir->open) {
137			if (ir->jiffies_to_wait) {
138				set_current_state(TASK_INTERRUPTIBLE);
139				schedule_timeout(ir->jiffies_to_wait);
140			}
141			if (kthread_should_stop())
142				break;
143			if (!add_to_buf(ir))
144				wake_up_interruptible(&ir->buf->wait_poll);
145		} else {
146			set_current_state(TASK_INTERRUPTIBLE);
147			schedule();
148		}
149	} while (!kthread_should_stop());
150
151	dev_dbg(ir->d.dev, LOGHEAD "poll thread ended\n",
152		ir->d.name, ir->d.minor);
153
154	return 0;
155}
156
157
158static struct file_operations fops = {
159	.owner		= THIS_MODULE,
160	.read		= lirc_dev_fop_read,
161	.write		= lirc_dev_fop_write,
162	.poll		= lirc_dev_fop_poll,
163	.unlocked_ioctl	= lirc_dev_fop_ioctl,
164	.open		= lirc_dev_fop_open,
165	.release	= lirc_dev_fop_close,
166};
167
168static int lirc_cdev_add(struct irctl *ir)
169{
170	int retval;
171	struct lirc_driver *d = &ir->d;
172
173	if (d->fops) {
174		cdev_init(&ir->cdev, d->fops);
175		ir->cdev.owner = d->owner;
176	} else {
177		cdev_init(&ir->cdev, &fops);
178		ir->cdev.owner = THIS_MODULE;
179	}
180	kobject_set_name(&ir->cdev.kobj, "lirc%d", d->minor);
181
182	retval = cdev_add(&ir->cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1);
183	if (retval)
184		kobject_put(&ir->cdev.kobj);
185
186	return retval;
187}
188
189int lirc_register_driver(struct lirc_driver *d)
190{
191	struct irctl *ir;
192	int minor;
193	int bytes_in_key;
194	unsigned int chunk_size;
195	unsigned int buffer_size;
196	int err;
197
198	if (!d) {
199		printk(KERN_ERR "lirc_dev: lirc_register_driver: "
200		       "driver pointer must be not NULL!\n");
201		err = -EBADRQC;
202		goto out;
203	}
204
205	if (MAX_IRCTL_DEVICES <= d->minor) {
206		dev_err(d->dev, "lirc_dev: lirc_register_driver: "
207			"\"minor\" must be between 0 and %d (%d)!\n",
208			MAX_IRCTL_DEVICES-1, d->minor);
209		err = -EBADRQC;
210		goto out;
211	}
212
213	if (1 > d->code_length || (BUFLEN * 8) < d->code_length) {
214		dev_err(d->dev, "lirc_dev: lirc_register_driver: "
215			"code length in bits for minor (%d) "
216			"must be less than %d!\n",
217			d->minor, BUFLEN * 8);
218		err = -EBADRQC;
219		goto out;
220	}
221
222	dev_dbg(d->dev, "lirc_dev: lirc_register_driver: sample_rate: %d\n",
223		d->sample_rate);
224	if (d->sample_rate) {
225		if (2 > d->sample_rate || HZ < d->sample_rate) {
226			dev_err(d->dev, "lirc_dev: lirc_register_driver: "
227				"sample_rate must be between 2 and %d!\n", HZ);
228			err = -EBADRQC;
229			goto out;
230		}
231		if (!d->add_to_buf) {
232			dev_err(d->dev, "lirc_dev: lirc_register_driver: "
233				"add_to_buf cannot be NULL when "
234				"sample_rate is set\n");
235			err = -EBADRQC;
236			goto out;
237		}
238	} else if (!(d->fops && d->fops->read) && !d->rbuf) {
239		dev_err(d->dev, "lirc_dev: lirc_register_driver: "
240			"fops->read and rbuf cannot all be NULL!\n");
241		err = -EBADRQC;
242		goto out;
243	} else if (!d->rbuf) {
244		if (!(d->fops && d->fops->read && d->fops->poll &&
245		      d->fops->unlocked_ioctl)) {
246			dev_err(d->dev, "lirc_dev: lirc_register_driver: "
247				"neither read, poll nor unlocked_ioctl can be NULL!\n");
248			err = -EBADRQC;
249			goto out;
250		}
251	}
252
253	mutex_lock(&lirc_dev_lock);
254
255	minor = d->minor;
256
257	if (minor < 0) {
258		/* find first free slot for driver */
259		for (minor = 0; minor < MAX_IRCTL_DEVICES; minor++)
260			if (!irctls[minor])
261				break;
262		if (MAX_IRCTL_DEVICES == minor) {
263			dev_err(d->dev, "lirc_dev: lirc_register_driver: "
264				"no free slots for drivers!\n");
265			err = -ENOMEM;
266			goto out_lock;
267		}
268	} else if (irctls[minor]) {
269		dev_err(d->dev, "lirc_dev: lirc_register_driver: "
270			"minor (%d) just registered!\n", minor);
271		err = -EBUSY;
272		goto out_lock;
273	}
274
275	ir = kzalloc(sizeof(struct irctl), GFP_KERNEL);
276	if (!ir) {
277		err = -ENOMEM;
278		goto out_lock;
279	}
280	init_irctl(ir);
281	irctls[minor] = ir;
282	d->minor = minor;
283
284	if (d->sample_rate) {
285		ir->jiffies_to_wait = HZ / d->sample_rate;
286	} else {
287		/* it means - wait for external event in task queue */
288		ir->jiffies_to_wait = 0;
289	}
290
291	/* some safety check 8-) */
292	d->name[sizeof(d->name)-1] = '\0';
293
294	bytes_in_key = BITS_TO_LONGS(d->code_length) +
295			(d->code_length % 8 ? 1 : 0);
296	buffer_size = d->buffer_size ? d->buffer_size : BUFLEN / bytes_in_key;
297	chunk_size  = d->chunk_size  ? d->chunk_size  : bytes_in_key;
298
299	if (d->rbuf) {
300		ir->buf = d->rbuf;
301	} else {
302		ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
303		if (!ir->buf) {
304			err = -ENOMEM;
305			goto out_lock;
306		}
307		err = lirc_buffer_init(ir->buf, chunk_size, buffer_size);
308		if (err) {
309			kfree(ir->buf);
310			goto out_lock;
311		}
312	}
313	ir->chunk_size = ir->buf->chunk_size;
314
315	if (d->features == 0)
316		d->features = LIRC_CAN_REC_LIRCCODE;
317
318	ir->d = *d;
319	ir->d.minor = minor;
320
321	device_create(lirc_class, ir->d.dev,
322		      MKDEV(MAJOR(lirc_base_dev), ir->d.minor), NULL,
323		      "lirc%u", ir->d.minor);
324
325	if (d->sample_rate) {
326		/* try to fire up polling thread */
327		ir->task = kthread_run(lirc_thread, (void *)ir, "lirc_dev");
328		if (IS_ERR(ir->task)) {
329			dev_err(d->dev, "lirc_dev: lirc_register_driver: "
330				"cannot run poll thread for minor = %d\n",
331				d->minor);
332			err = -ECHILD;
333			goto out_sysfs;
334		}
335	}
336
337	err = lirc_cdev_add(ir);
338	if (err)
339		goto out_sysfs;
340
341	ir->attached = 1;
342	mutex_unlock(&lirc_dev_lock);
343
344	dev_info(ir->d.dev, "lirc_dev: driver %s registered at minor = %d\n",
345		 ir->d.name, ir->d.minor);
346	return minor;
347
348out_sysfs:
349	device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor));
350out_lock:
351	mutex_unlock(&lirc_dev_lock);
352out:
353	return err;
354}
355EXPORT_SYMBOL(lirc_register_driver);
356
357int lirc_unregister_driver(int minor)
358{
359	struct irctl *ir;
360
361	if (minor < 0 || minor >= MAX_IRCTL_DEVICES) {
362		printk(KERN_ERR "lirc_dev: lirc_unregister_driver: "
363		       "\"minor (%d)\" must be between 0 and %d!\n",
364		       minor, MAX_IRCTL_DEVICES-1);
365		return -EBADRQC;
366	}
367
368	ir = irctls[minor];
369
370	mutex_lock(&lirc_dev_lock);
371
372	if (ir->d.minor != minor) {
373		printk(KERN_ERR "lirc_dev: lirc_unregister_driver: "
374		       "minor (%d) device not registered!", minor);
375		mutex_unlock(&lirc_dev_lock);
376		return -ENOENT;
377	}
378
379	/* end up polling thread */
380	if (ir->task)
381		kthread_stop(ir->task);
382
383	dev_dbg(ir->d.dev, "lirc_dev: driver %s unregistered from minor = %d\n",
384		ir->d.name, ir->d.minor);
385
386	ir->attached = 0;
387	if (ir->open) {
388		dev_dbg(ir->d.dev, LOGHEAD "releasing opened driver\n",
389			ir->d.name, ir->d.minor);
390		wake_up_interruptible(&ir->buf->wait_poll);
391		mutex_lock(&ir->irctl_lock);
392		ir->d.set_use_dec(ir->d.data);
393		module_put(ir->d.owner);
394		mutex_unlock(&ir->irctl_lock);
395		cdev_del(&ir->cdev);
396	} else {
397		cleanup(ir);
398		cdev_del(&ir->cdev);
399		kfree(ir);
400		irctls[minor] = NULL;
401	}
402
403	mutex_unlock(&lirc_dev_lock);
404
405	return 0;
406}
407EXPORT_SYMBOL(lirc_unregister_driver);
408
409int lirc_dev_fop_open(struct inode *inode, struct file *file)
410{
411	struct irctl *ir;
412	int retval = 0;
413
414	if (iminor(inode) >= MAX_IRCTL_DEVICES) {
415		printk(KERN_WARNING "lirc_dev [%d]: open result = -ENODEV\n",
416		       iminor(inode));
417		return -ENODEV;
418	}
419
420	if (mutex_lock_interruptible(&lirc_dev_lock))
421		return -ERESTARTSYS;
422
423	ir = irctls[iminor(inode)];
424	if (!ir) {
425		retval = -ENODEV;
426		goto error;
427	}
428	file->private_data = ir;
429
430	dev_dbg(ir->d.dev, LOGHEAD "open called\n", ir->d.name, ir->d.minor);
431
432	if (ir->d.minor == NOPLUG) {
433		retval = -ENODEV;
434		goto error;
435	}
436
437	if (ir->open) {
438		retval = -EBUSY;
439		goto error;
440	}
441
442	if (try_module_get(ir->d.owner)) {
443		++ir->open;
444		retval = ir->d.set_use_inc(ir->d.data);
445
446		if (retval) {
447			module_put(ir->d.owner);
448			--ir->open;
449		} else {
450			lirc_buffer_clear(ir->buf);
451		}
452		if (ir->task)
453			wake_up_process(ir->task);
454	}
455
456error:
457	if (ir)
458		dev_dbg(ir->d.dev, LOGHEAD "open result = %d\n",
459			ir->d.name, ir->d.minor, retval);
460
461	mutex_unlock(&lirc_dev_lock);
462
463	return retval;
464}
465EXPORT_SYMBOL(lirc_dev_fop_open);
466
467int lirc_dev_fop_close(struct inode *inode, struct file *file)
468{
469	struct irctl *ir = irctls[iminor(inode)];
470
471	dev_dbg(ir->d.dev, LOGHEAD "close called\n", ir->d.name, ir->d.minor);
472
473	WARN_ON(mutex_lock_killable(&lirc_dev_lock));
474
475	--ir->open;
476	if (ir->attached) {
477		ir->d.set_use_dec(ir->d.data);
478		module_put(ir->d.owner);
479	} else {
480		cleanup(ir);
481		irctls[ir->d.minor] = NULL;
482		kfree(ir);
483	}
484
485	mutex_unlock(&lirc_dev_lock);
486
487	return 0;
488}
489EXPORT_SYMBOL(lirc_dev_fop_close);
490
491unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait)
492{
493	struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
494	unsigned int ret;
495
496	dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor);
497
498	if (!ir->attached) {
499		mutex_unlock(&ir->irctl_lock);
500		return POLLERR;
501	}
502
503	poll_wait(file, &ir->buf->wait_poll, wait);
504
505	if (ir->buf)
506		if (lirc_buffer_empty(ir->buf))
507			ret = 0;
508		else
509			ret = POLLIN | POLLRDNORM;
510	else
511		ret = POLLERR;
512
513	dev_dbg(ir->d.dev, LOGHEAD "poll result = %d\n",
514		ir->d.name, ir->d.minor, ret);
515
516	return ret;
517}
518EXPORT_SYMBOL(lirc_dev_fop_poll);
519
520long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
521{
522	unsigned long mode;
523	int result = 0;
524	struct irctl *ir = file->private_data;
525
526	dev_dbg(ir->d.dev, LOGHEAD "ioctl called (0x%x)\n",
527		ir->d.name, ir->d.minor, cmd);
528
529	if (ir->d.minor == NOPLUG || !ir->attached) {
530		dev_dbg(ir->d.dev, LOGHEAD "ioctl result = -ENODEV\n",
531			ir->d.name, ir->d.minor);
532		return -ENODEV;
533	}
534
535	mutex_lock(&ir->irctl_lock);
536
537	switch (cmd) {
538	case LIRC_GET_FEATURES:
539		result = put_user(ir->d.features, (unsigned long *)arg);
540		break;
541	case LIRC_GET_REC_MODE:
542		if (!(ir->d.features & LIRC_CAN_REC_MASK)) {
543			result = -ENOSYS;
544			break;
545		}
546
547		result = put_user(LIRC_REC2MODE
548				  (ir->d.features & LIRC_CAN_REC_MASK),
549				  (unsigned long *)arg);
550		break;
551	case LIRC_SET_REC_MODE:
552		if (!(ir->d.features & LIRC_CAN_REC_MASK)) {
553			result = -ENOSYS;
554			break;
555		}
556
557		result = get_user(mode, (unsigned long *)arg);
558		if (!result && !(LIRC_MODE2REC(mode) & ir->d.features))
559			result = -EINVAL;
560		break;
561	case LIRC_GET_LENGTH:
562		result = put_user(ir->d.code_length, (unsigned long *)arg);
563		break;
564	case LIRC_GET_MIN_TIMEOUT:
565		if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
566		    ir->d.min_timeout == 0) {
567			result = -ENOSYS;
568			break;
569		}
570
571		result = put_user(ir->d.min_timeout, (unsigned long *)arg);
572		break;
573	case LIRC_GET_MAX_TIMEOUT:
574		if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
575		    ir->d.max_timeout == 0) {
576			result = -ENOSYS;
577			break;
578		}
579
580		result = put_user(ir->d.max_timeout, (unsigned long *)arg);
581		break;
582	default:
583		result = -EINVAL;
584	}
585
586	dev_dbg(ir->d.dev, LOGHEAD "ioctl result = %d\n",
587		ir->d.name, ir->d.minor, result);
588
589	mutex_unlock(&ir->irctl_lock);
590
591	return result;
592}
593EXPORT_SYMBOL(lirc_dev_fop_ioctl);
594
595ssize_t lirc_dev_fop_read(struct file *file,
596			  char *buffer,
597			  size_t length,
598			  loff_t *ppos)
599{
600	struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
601	unsigned char buf[ir->chunk_size];
602	int ret = 0, written = 0;
603	DECLARE_WAITQUEUE(wait, current);
604
605	dev_dbg(ir->d.dev, LOGHEAD "read called\n", ir->d.name, ir->d.minor);
606
607	if (mutex_lock_interruptible(&ir->irctl_lock))
608		return -ERESTARTSYS;
609	if (!ir->attached) {
610		mutex_unlock(&ir->irctl_lock);
611		return -ENODEV;
612	}
613
614	if (length % ir->chunk_size) {
615		dev_dbg(ir->d.dev, LOGHEAD "read result = -EINVAL\n",
616			ir->d.name, ir->d.minor);
617		mutex_unlock(&ir->irctl_lock);
618		return -EINVAL;
619	}
620
621	/*
622	 * we add ourselves to the task queue before buffer check
623	 * to avoid losing scan code (in case when queue is awaken somewhere
624	 * between while condition checking and scheduling)
625	 */
626	add_wait_queue(&ir->buf->wait_poll, &wait);
627	set_current_state(TASK_INTERRUPTIBLE);
628
629	/*
630	 * while we didn't provide 'length' bytes, device is opened in blocking
631	 * mode and 'copy_to_user' is happy, wait for data.
632	 */
633	while (written < length && ret == 0) {
634		if (lirc_buffer_empty(ir->buf)) {
635			/* According to the read(2) man page, 'written' can be
636			 * returned as less than 'length', instead of blocking
637			 * again, returning -EWOULDBLOCK, or returning
638			 * -ERESTARTSYS */
639			if (written)
640				break;
641			if (file->f_flags & O_NONBLOCK) {
642				ret = -EWOULDBLOCK;
643				break;
644			}
645			if (signal_pending(current)) {
646				ret = -ERESTARTSYS;
647				break;
648			}
649
650			mutex_unlock(&ir->irctl_lock);
651			schedule();
652			set_current_state(TASK_INTERRUPTIBLE);
653
654			if (mutex_lock_interruptible(&ir->irctl_lock)) {
655				ret = -ERESTARTSYS;
656				remove_wait_queue(&ir->buf->wait_poll, &wait);
657				set_current_state(TASK_RUNNING);
658				goto out_unlocked;
659			}
660
661			if (!ir->attached) {
662				ret = -ENODEV;
663				break;
664			}
665		} else {
666			lirc_buffer_read(ir->buf, buf);
667			ret = copy_to_user((void *)buffer+written, buf,
668					   ir->buf->chunk_size);
669			written += ir->buf->chunk_size;
670		}
671	}
672
673	remove_wait_queue(&ir->buf->wait_poll, &wait);
674	set_current_state(TASK_RUNNING);
675	mutex_unlock(&ir->irctl_lock);
676
677out_unlocked:
678	dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n",
679		ir->d.name, ir->d.minor, ret ? "-EFAULT" : "OK", ret);
680
681	return ret ? ret : written;
682}
683EXPORT_SYMBOL(lirc_dev_fop_read);
684
685void *lirc_get_pdata(struct file *file)
686{
687	void *data = NULL;
688
689	if (file && file->f_dentry && file->f_dentry->d_inode &&
690	    file->f_dentry->d_inode->i_rdev) {
691		struct irctl *ir;
692		ir = irctls[iminor(file->f_dentry->d_inode)];
693		data = ir->d.data;
694	}
695
696	return data;
697}
698EXPORT_SYMBOL(lirc_get_pdata);
699
700
701ssize_t lirc_dev_fop_write(struct file *file, const char *buffer,
702			   size_t length, loff_t *ppos)
703{
704	struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
705
706	dev_dbg(ir->d.dev, LOGHEAD "write called\n", ir->d.name, ir->d.minor);
707
708	if (!ir->attached)
709		return -ENODEV;
710
711	return -EINVAL;
712}
713EXPORT_SYMBOL(lirc_dev_fop_write);
714
715
716static int __init lirc_dev_init(void)
717{
718	int retval;
719
720	lirc_class = class_create(THIS_MODULE, "lirc");
721	if (IS_ERR(lirc_class)) {
722		retval = PTR_ERR(lirc_class);
723		printk(KERN_ERR "lirc_dev: class_create failed\n");
724		goto error;
725	}
726
727	retval = alloc_chrdev_region(&lirc_base_dev, 0, MAX_IRCTL_DEVICES,
728				     IRCTL_DEV_NAME);
729	if (retval) {
730		class_destroy(lirc_class);
731		printk(KERN_ERR "lirc_dev: alloc_chrdev_region failed\n");
732		goto error;
733	}
734
735
736	printk(KERN_INFO "lirc_dev: IR Remote Control driver registered, "
737	       "major %d \n", MAJOR(lirc_base_dev));
738
739error:
740	return retval;
741}
742
743
744
745static void __exit lirc_dev_exit(void)
746{
747	class_destroy(lirc_class);
748	unregister_chrdev_region(lirc_base_dev, MAX_IRCTL_DEVICES);
749	printk(KERN_INFO "lirc_dev: module unloaded\n");
750}
751
752module_init(lirc_dev_init);
753module_exit(lirc_dev_exit);
754
755MODULE_DESCRIPTION("LIRC base driver module");
756MODULE_AUTHOR("Artur Lipowski");
757MODULE_LICENSE("GPL");
758
759module_param(debug, bool, S_IRUGO | S_IWUSR);
760MODULE_PARM_DESC(debug, "Enable debugging messages");
761