845 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * LIRC base driver4 *5 * by Artur Lipowski <alipowski@interia.pl>6 */7 8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt9 10#include <linux/module.h>11#include <linux/mutex.h>12#include <linux/device.h>13#include <linux/file.h>14#include <linux/idr.h>15#include <linux/poll.h>16#include <linux/sched.h>17#include <linux/wait.h>18 19#include "rc-core-priv.h"20#include <uapi/linux/lirc.h>21 22#define LIRCBUF_SIZE 102423 24static dev_t lirc_base_dev;25 26/* Used to keep track of allocated lirc devices */27static DEFINE_IDA(lirc_ida);28 29/* Only used for sysfs but defined to void otherwise */30static const struct class lirc_class = {31 .name = "lirc",32};33 34/**35 * lirc_raw_event() - Send raw IR data to lirc to be relayed to userspace36 *37 * @dev: the struct rc_dev descriptor of the device38 * @ev: the struct ir_raw_event descriptor of the pulse/space39 */40void lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev)41{42 unsigned long flags;43 struct lirc_fh *fh;44 int sample;45 46 /* Receiver overflow, data missing */47 if (ev.overflow) {48 /*49 * Send lirc overflow message. This message is unknown to50 * lircd, but it will interpret this as a long space as51 * long as the value is set to high value. This resets its52 * decoder state.53 */54 sample = LIRC_OVERFLOW(LIRC_VALUE_MASK);55 dev_dbg(&dev->dev, "delivering overflow to lirc_dev\n");56 57 /* Carrier reports */58 } else if (ev.carrier_report) {59 sample = LIRC_FREQUENCY(ev.carrier);60 dev_dbg(&dev->dev, "carrier report (freq: %d)\n", sample);61 62 /* Packet end */63 } else if (ev.timeout) {64 dev->gap_start = ktime_get();65 66 sample = LIRC_TIMEOUT(ev.duration);67 dev_dbg(&dev->dev, "timeout report (duration: %d)\n", sample);68 69 /* Normal sample */70 } else {71 if (dev->gap_start) {72 u64 duration = ktime_us_delta(ktime_get(),73 dev->gap_start);74 75 /* Cap by LIRC_VALUE_MASK */76 duration = min_t(u64, duration, LIRC_VALUE_MASK);77 78 spin_lock_irqsave(&dev->lirc_fh_lock, flags);79 list_for_each_entry(fh, &dev->lirc_fh, list)80 kfifo_put(&fh->rawir, LIRC_SPACE(duration));81 spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);82 dev->gap_start = 0;83 }84 85 sample = ev.pulse ? LIRC_PULSE(ev.duration) :86 LIRC_SPACE(ev.duration);87 dev_dbg(&dev->dev, "delivering %uus %s to lirc_dev\n",88 ev.duration, TO_STR(ev.pulse));89 }90 91 /*92 * bpf does not care about the gap generated above; that exists93 * for backwards compatibility94 */95 lirc_bpf_run(dev, sample);96 97 spin_lock_irqsave(&dev->lirc_fh_lock, flags);98 list_for_each_entry(fh, &dev->lirc_fh, list) {99 if (kfifo_put(&fh->rawir, sample))100 wake_up_poll(&fh->wait_poll, EPOLLIN | EPOLLRDNORM);101 }102 spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);103}104 105/**106 * lirc_scancode_event() - Send scancode data to lirc to be relayed to107 * userspace. This can be called in atomic context.108 * @dev: the struct rc_dev descriptor of the device109 * @lsc: the struct lirc_scancode describing the decoded scancode110 */111void lirc_scancode_event(struct rc_dev *dev, struct lirc_scancode *lsc)112{113 unsigned long flags;114 struct lirc_fh *fh;115 116 lsc->timestamp = ktime_get_ns();117 118 spin_lock_irqsave(&dev->lirc_fh_lock, flags);119 list_for_each_entry(fh, &dev->lirc_fh, list) {120 if (kfifo_put(&fh->scancodes, *lsc))121 wake_up_poll(&fh->wait_poll, EPOLLIN | EPOLLRDNORM);122 }123 spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);124}125EXPORT_SYMBOL_GPL(lirc_scancode_event);126 127static int lirc_open(struct inode *inode, struct file *file)128{129 struct rc_dev *dev = container_of(inode->i_cdev, struct rc_dev,130 lirc_cdev);131 struct lirc_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL);132 unsigned long flags;133 int retval;134 135 if (!fh)136 return -ENOMEM;137 138 get_device(&dev->dev);139 140 if (!dev->registered) {141 retval = -ENODEV;142 goto out_fh;143 }144 145 if (dev->driver_type == RC_DRIVER_IR_RAW) {146 if (kfifo_alloc(&fh->rawir, MAX_IR_EVENT_SIZE, GFP_KERNEL)) {147 retval = -ENOMEM;148 goto out_fh;149 }150 }151 152 if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {153 if (kfifo_alloc(&fh->scancodes, 32, GFP_KERNEL)) {154 retval = -ENOMEM;155 goto out_rawir;156 }157 }158 159 fh->send_mode = LIRC_MODE_PULSE;160 fh->rc = dev;161 162 if (dev->driver_type == RC_DRIVER_SCANCODE)163 fh->rec_mode = LIRC_MODE_SCANCODE;164 else165 fh->rec_mode = LIRC_MODE_MODE2;166 167 retval = rc_open(dev);168 if (retval)169 goto out_kfifo;170 171 init_waitqueue_head(&fh->wait_poll);172 173 file->private_data = fh;174 spin_lock_irqsave(&dev->lirc_fh_lock, flags);175 list_add(&fh->list, &dev->lirc_fh);176 spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);177 178 stream_open(inode, file);179 180 return 0;181out_kfifo:182 if (dev->driver_type != RC_DRIVER_IR_RAW_TX)183 kfifo_free(&fh->scancodes);184out_rawir:185 if (dev->driver_type == RC_DRIVER_IR_RAW)186 kfifo_free(&fh->rawir);187out_fh:188 kfree(fh);189 put_device(&dev->dev);190 191 return retval;192}193 194static int lirc_close(struct inode *inode, struct file *file)195{196 struct lirc_fh *fh = file->private_data;197 struct rc_dev *dev = fh->rc;198 unsigned long flags;199 200 spin_lock_irqsave(&dev->lirc_fh_lock, flags);201 list_del(&fh->list);202 spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);203 204 if (dev->driver_type == RC_DRIVER_IR_RAW)205 kfifo_free(&fh->rawir);206 if (dev->driver_type != RC_DRIVER_IR_RAW_TX)207 kfifo_free(&fh->scancodes);208 kfree(fh);209 210 rc_close(dev);211 put_device(&dev->dev);212 213 return 0;214}215 216static ssize_t lirc_transmit(struct file *file, const char __user *buf,217 size_t n, loff_t *ppos)218{219 struct lirc_fh *fh = file->private_data;220 struct rc_dev *dev = fh->rc;221 unsigned int *txbuf;222 struct ir_raw_event *raw = NULL;223 ssize_t ret;224 size_t count;225 ktime_t start;226 s64 towait;227 unsigned int duration = 0; /* signal duration in us */228 int i;229 230 ret = mutex_lock_interruptible(&dev->lock);231 if (ret)232 return ret;233 234 if (!dev->registered) {235 ret = -ENODEV;236 goto out_unlock;237 }238 239 if (!dev->tx_ir) {240 ret = -EINVAL;241 goto out_unlock;242 }243 244 if (fh->send_mode == LIRC_MODE_SCANCODE) {245 struct lirc_scancode scan;246 247 if (n != sizeof(scan)) {248 ret = -EINVAL;249 goto out_unlock;250 }251 252 if (copy_from_user(&scan, buf, sizeof(scan))) {253 ret = -EFAULT;254 goto out_unlock;255 }256 257 if (scan.flags || scan.keycode || scan.timestamp ||258 scan.rc_proto > RC_PROTO_MAX) {259 ret = -EINVAL;260 goto out_unlock;261 }262 263 /* We only have encoders for 32-bit protocols. */264 if (scan.scancode > U32_MAX ||265 !rc_validate_scancode(scan.rc_proto, scan.scancode)) {266 ret = -EINVAL;267 goto out_unlock;268 }269 270 raw = kmalloc_array(LIRCBUF_SIZE, sizeof(*raw), GFP_KERNEL);271 if (!raw) {272 ret = -ENOMEM;273 goto out_unlock;274 }275 276 ret = ir_raw_encode_scancode(scan.rc_proto, scan.scancode,277 raw, LIRCBUF_SIZE);278 if (ret < 0)279 goto out_kfree_raw;280 281 /* drop trailing space */282 if (!(ret % 2))283 count = ret - 1;284 else285 count = ret;286 287 txbuf = kmalloc_array(count, sizeof(unsigned int), GFP_KERNEL);288 if (!txbuf) {289 ret = -ENOMEM;290 goto out_kfree_raw;291 }292 293 for (i = 0; i < count; i++)294 txbuf[i] = raw[i].duration;295 296 if (dev->s_tx_carrier) {297 int carrier = ir_raw_encode_carrier(scan.rc_proto);298 299 if (carrier > 0)300 dev->s_tx_carrier(dev, carrier);301 }302 } else {303 if (n < sizeof(unsigned int) || n % sizeof(unsigned int)) {304 ret = -EINVAL;305 goto out_unlock;306 }307 308 count = n / sizeof(unsigned int);309 if (count > LIRCBUF_SIZE || count % 2 == 0) {310 ret = -EINVAL;311 goto out_unlock;312 }313 314 txbuf = memdup_user(buf, n);315 if (IS_ERR(txbuf)) {316 ret = PTR_ERR(txbuf);317 goto out_unlock;318 }319 }320 321 for (i = 0; i < count; i++) {322 if (txbuf[i] > IR_MAX_DURATION - duration || !txbuf[i]) {323 ret = -EINVAL;324 goto out_kfree;325 }326 327 duration += txbuf[i];328 }329 330 start = ktime_get();331 332 ret = dev->tx_ir(dev, txbuf, count);333 if (ret < 0)334 goto out_kfree;335 336 kfree(txbuf);337 kfree(raw);338 mutex_unlock(&dev->lock);339 340 /*341 * The lircd gap calculation expects the write function to342 * wait for the actual IR signal to be transmitted before343 * returning.344 */345 towait = ktime_us_delta(ktime_add_us(start, duration),346 ktime_get());347 if (towait > 0) {348 set_current_state(TASK_INTERRUPTIBLE);349 schedule_timeout(usecs_to_jiffies(towait));350 }351 352 return n;353out_kfree:354 kfree(txbuf);355out_kfree_raw:356 kfree(raw);357out_unlock:358 mutex_unlock(&dev->lock);359 return ret;360}361 362static long lirc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)363{364 struct lirc_fh *fh = file->private_data;365 struct rc_dev *dev = fh->rc;366 u32 __user *argp = (u32 __user *)(arg);367 u32 val = 0;368 int ret;369 370 if (_IOC_DIR(cmd) & _IOC_WRITE) {371 ret = get_user(val, argp);372 if (ret)373 return ret;374 }375 376 ret = mutex_lock_interruptible(&dev->lock);377 if (ret)378 return ret;379 380 if (!dev->registered) {381 ret = -ENODEV;382 goto out;383 }384 385 switch (cmd) {386 case LIRC_GET_FEATURES:387 if (dev->driver_type == RC_DRIVER_SCANCODE)388 val |= LIRC_CAN_REC_SCANCODE;389 390 if (dev->driver_type == RC_DRIVER_IR_RAW) {391 val |= LIRC_CAN_REC_MODE2;392 if (dev->rx_resolution)393 val |= LIRC_CAN_GET_REC_RESOLUTION;394 }395 396 if (dev->tx_ir) {397 val |= LIRC_CAN_SEND_PULSE;398 if (dev->s_tx_mask)399 val |= LIRC_CAN_SET_TRANSMITTER_MASK;400 if (dev->s_tx_carrier)401 val |= LIRC_CAN_SET_SEND_CARRIER;402 if (dev->s_tx_duty_cycle)403 val |= LIRC_CAN_SET_SEND_DUTY_CYCLE;404 }405 406 if (dev->s_rx_carrier_range)407 val |= LIRC_CAN_SET_REC_CARRIER |408 LIRC_CAN_SET_REC_CARRIER_RANGE;409 410 if (dev->s_wideband_receiver)411 val |= LIRC_CAN_USE_WIDEBAND_RECEIVER;412 413 if (dev->s_carrier_report)414 val |= LIRC_CAN_MEASURE_CARRIER;415 416 if (dev->max_timeout)417 val |= LIRC_CAN_SET_REC_TIMEOUT;418 419 break;420 421 /* mode support */422 case LIRC_GET_REC_MODE:423 if (dev->driver_type == RC_DRIVER_IR_RAW_TX)424 ret = -ENOTTY;425 else426 val = fh->rec_mode;427 break;428 429 case LIRC_SET_REC_MODE:430 switch (dev->driver_type) {431 case RC_DRIVER_IR_RAW_TX:432 ret = -ENOTTY;433 break;434 case RC_DRIVER_SCANCODE:435 if (val != LIRC_MODE_SCANCODE)436 ret = -EINVAL;437 break;438 case RC_DRIVER_IR_RAW:439 if (!(val == LIRC_MODE_MODE2 ||440 val == LIRC_MODE_SCANCODE))441 ret = -EINVAL;442 break;443 }444 445 if (!ret)446 fh->rec_mode = val;447 break;448 449 case LIRC_GET_SEND_MODE:450 if (!dev->tx_ir)451 ret = -ENOTTY;452 else453 val = fh->send_mode;454 break;455 456 case LIRC_SET_SEND_MODE:457 if (!dev->tx_ir)458 ret = -ENOTTY;459 else if (!(val == LIRC_MODE_PULSE || val == LIRC_MODE_SCANCODE))460 ret = -EINVAL;461 else462 fh->send_mode = val;463 break;464 465 /* TX settings */466 case LIRC_SET_TRANSMITTER_MASK:467 if (!dev->s_tx_mask)468 ret = -ENOTTY;469 else470 ret = dev->s_tx_mask(dev, val);471 break;472 473 case LIRC_SET_SEND_CARRIER:474 if (!dev->s_tx_carrier)475 ret = -ENOTTY;476 else477 ret = dev->s_tx_carrier(dev, val);478 break;479 480 case LIRC_SET_SEND_DUTY_CYCLE:481 if (!dev->s_tx_duty_cycle)482 ret = -ENOTTY;483 else if (val <= 0 || val >= 100)484 ret = -EINVAL;485 else486 ret = dev->s_tx_duty_cycle(dev, val);487 break;488 489 /* RX settings */490 case LIRC_SET_REC_CARRIER:491 if (!dev->s_rx_carrier_range)492 ret = -ENOTTY;493 else if (val <= 0)494 ret = -EINVAL;495 else496 ret = dev->s_rx_carrier_range(dev, fh->carrier_low,497 val);498 break;499 500 case LIRC_SET_REC_CARRIER_RANGE:501 if (!dev->s_rx_carrier_range)502 ret = -ENOTTY;503 else if (val <= 0)504 ret = -EINVAL;505 else506 fh->carrier_low = val;507 break;508 509 case LIRC_GET_REC_RESOLUTION:510 if (!dev->rx_resolution)511 ret = -ENOTTY;512 else513 val = dev->rx_resolution;514 break;515 516 case LIRC_SET_WIDEBAND_RECEIVER:517 if (!dev->s_wideband_receiver)518 ret = -ENOTTY;519 else520 ret = dev->s_wideband_receiver(dev, !!val);521 break;522 523 case LIRC_SET_MEASURE_CARRIER_MODE:524 if (!dev->s_carrier_report)525 ret = -ENOTTY;526 else527 ret = dev->s_carrier_report(dev, !!val);528 break;529 530 /* Generic timeout support */531 case LIRC_GET_MIN_TIMEOUT:532 if (!dev->max_timeout)533 ret = -ENOTTY;534 else535 val = dev->min_timeout;536 break;537 538 case LIRC_GET_MAX_TIMEOUT:539 if (!dev->max_timeout)540 ret = -ENOTTY;541 else542 val = dev->max_timeout;543 break;544 545 case LIRC_SET_REC_TIMEOUT:546 if (!dev->max_timeout) {547 ret = -ENOTTY;548 } else {549 if (val < dev->min_timeout || val > dev->max_timeout)550 ret = -EINVAL;551 else if (dev->s_timeout)552 ret = dev->s_timeout(dev, val);553 else554 dev->timeout = val;555 }556 break;557 558 case LIRC_GET_REC_TIMEOUT:559 if (!dev->timeout)560 ret = -ENOTTY;561 else562 val = dev->timeout;563 break;564 565 case LIRC_SET_REC_TIMEOUT_REPORTS:566 if (dev->driver_type != RC_DRIVER_IR_RAW)567 ret = -ENOTTY;568 break;569 570 default:571 ret = -ENOTTY;572 }573 574 if (!ret && _IOC_DIR(cmd) & _IOC_READ)575 ret = put_user(val, argp);576 577out:578 mutex_unlock(&dev->lock);579 return ret;580}581 582static __poll_t lirc_poll(struct file *file, struct poll_table_struct *wait)583{584 struct lirc_fh *fh = file->private_data;585 struct rc_dev *rcdev = fh->rc;586 __poll_t events = 0;587 588 poll_wait(file, &fh->wait_poll, wait);589 590 if (!rcdev->registered) {591 events = EPOLLHUP | EPOLLERR;592 } else if (rcdev->driver_type != RC_DRIVER_IR_RAW_TX) {593 if (fh->rec_mode == LIRC_MODE_SCANCODE &&594 !kfifo_is_empty(&fh->scancodes))595 events = EPOLLIN | EPOLLRDNORM;596 597 if (fh->rec_mode == LIRC_MODE_MODE2 &&598 !kfifo_is_empty(&fh->rawir))599 events = EPOLLIN | EPOLLRDNORM;600 }601 602 return events;603}604 605static ssize_t lirc_read_mode2(struct file *file, char __user *buffer,606 size_t length)607{608 struct lirc_fh *fh = file->private_data;609 struct rc_dev *rcdev = fh->rc;610 unsigned int copied;611 int ret;612 613 if (length < sizeof(unsigned int) || length % sizeof(unsigned int))614 return -EINVAL;615 616 do {617 if (kfifo_is_empty(&fh->rawir)) {618 if (file->f_flags & O_NONBLOCK)619 return -EAGAIN;620 621 ret = wait_event_interruptible(fh->wait_poll,622 !kfifo_is_empty(&fh->rawir) ||623 !rcdev->registered);624 if (ret)625 return ret;626 }627 628 if (!rcdev->registered)629 return -ENODEV;630 631 ret = mutex_lock_interruptible(&rcdev->lock);632 if (ret)633 return ret;634 ret = kfifo_to_user(&fh->rawir, buffer, length, &copied);635 mutex_unlock(&rcdev->lock);636 if (ret)637 return ret;638 } while (copied == 0);639 640 return copied;641}642 643static ssize_t lirc_read_scancode(struct file *file, char __user *buffer,644 size_t length)645{646 struct lirc_fh *fh = file->private_data;647 struct rc_dev *rcdev = fh->rc;648 unsigned int copied;649 int ret;650 651 if (length < sizeof(struct lirc_scancode) ||652 length % sizeof(struct lirc_scancode))653 return -EINVAL;654 655 do {656 if (kfifo_is_empty(&fh->scancodes)) {657 if (file->f_flags & O_NONBLOCK)658 return -EAGAIN;659 660 ret = wait_event_interruptible(fh->wait_poll,661 !kfifo_is_empty(&fh->scancodes) ||662 !rcdev->registered);663 if (ret)664 return ret;665 }666 667 if (!rcdev->registered)668 return -ENODEV;669 670 ret = mutex_lock_interruptible(&rcdev->lock);671 if (ret)672 return ret;673 ret = kfifo_to_user(&fh->scancodes, buffer, length, &copied);674 mutex_unlock(&rcdev->lock);675 if (ret)676 return ret;677 } while (copied == 0);678 679 return copied;680}681 682static ssize_t lirc_read(struct file *file, char __user *buffer, size_t length,683 loff_t *ppos)684{685 struct lirc_fh *fh = file->private_data;686 struct rc_dev *rcdev = fh->rc;687 688 if (rcdev->driver_type == RC_DRIVER_IR_RAW_TX)689 return -EINVAL;690 691 if (!rcdev->registered)692 return -ENODEV;693 694 if (fh->rec_mode == LIRC_MODE_MODE2)695 return lirc_read_mode2(file, buffer, length);696 else /* LIRC_MODE_SCANCODE */697 return lirc_read_scancode(file, buffer, length);698}699 700static const struct file_operations lirc_fops = {701 .owner = THIS_MODULE,702 .write = lirc_transmit,703 .unlocked_ioctl = lirc_ioctl,704 .compat_ioctl = compat_ptr_ioctl,705 .read = lirc_read,706 .poll = lirc_poll,707 .open = lirc_open,708 .release = lirc_close,709};710 711static void lirc_release_device(struct device *ld)712{713 struct rc_dev *rcdev = container_of(ld, struct rc_dev, lirc_dev);714 715 put_device(&rcdev->dev);716}717 718int lirc_register(struct rc_dev *dev)719{720 const char *rx_type, *tx_type;721 int err, minor;722 723 minor = ida_alloc_max(&lirc_ida, RC_DEV_MAX - 1, GFP_KERNEL);724 if (minor < 0)725 return minor;726 727 device_initialize(&dev->lirc_dev);728 dev->lirc_dev.class = &lirc_class;729 dev->lirc_dev.parent = &dev->dev;730 dev->lirc_dev.release = lirc_release_device;731 dev->lirc_dev.devt = MKDEV(MAJOR(lirc_base_dev), minor);732 dev_set_name(&dev->lirc_dev, "lirc%d", minor);733 734 INIT_LIST_HEAD(&dev->lirc_fh);735 spin_lock_init(&dev->lirc_fh_lock);736 737 cdev_init(&dev->lirc_cdev, &lirc_fops);738 739 err = cdev_device_add(&dev->lirc_cdev, &dev->lirc_dev);740 if (err)741 goto out_ida;742 743 get_device(&dev->dev);744 745 switch (dev->driver_type) {746 case RC_DRIVER_SCANCODE:747 rx_type = "scancode";748 break;749 case RC_DRIVER_IR_RAW:750 rx_type = "raw IR";751 break;752 default:753 rx_type = "no";754 break;755 }756 757 if (dev->tx_ir)758 tx_type = "raw IR";759 else760 tx_type = "no";761 762 dev_info(&dev->dev, "lirc_dev: driver %s registered at minor = %d, %s receiver, %s transmitter",763 dev->driver_name, minor, rx_type, tx_type);764 765 return 0;766 767out_ida:768 ida_free(&lirc_ida, minor);769 return err;770}771 772void lirc_unregister(struct rc_dev *dev)773{774 unsigned long flags;775 struct lirc_fh *fh;776 777 dev_dbg(&dev->dev, "lirc_dev: driver %s unregistered from minor = %d\n",778 dev->driver_name, MINOR(dev->lirc_dev.devt));779 780 spin_lock_irqsave(&dev->lirc_fh_lock, flags);781 list_for_each_entry(fh, &dev->lirc_fh, list)782 wake_up_poll(&fh->wait_poll, EPOLLHUP | EPOLLERR);783 spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);784 785 cdev_device_del(&dev->lirc_cdev, &dev->lirc_dev);786 ida_free(&lirc_ida, MINOR(dev->lirc_dev.devt));787}788 789int __init lirc_dev_init(void)790{791 int retval;792 793 retval = class_register(&lirc_class);794 if (retval)795 return retval;796 797 retval = alloc_chrdev_region(&lirc_base_dev, 0, RC_DEV_MAX, "lirc");798 if (retval) {799 class_unregister(&lirc_class);800 pr_err("alloc_chrdev_region failed\n");801 return retval;802 }803 804 pr_debug("IR Remote Control driver registered, major %d\n",805 MAJOR(lirc_base_dev));806 807 return 0;808}809 810void __exit lirc_dev_exit(void)811{812 class_unregister(&lirc_class);813 unregister_chrdev_region(lirc_base_dev, RC_DEV_MAX);814}815 816struct rc_dev *rc_dev_get_from_fd(int fd, bool write)817{818 struct fd f = fdget(fd);819 struct lirc_fh *fh;820 struct rc_dev *dev;821 822 if (!fd_file(f))823 return ERR_PTR(-EBADF);824 825 if (fd_file(f)->f_op != &lirc_fops) {826 fdput(f);827 return ERR_PTR(-EINVAL);828 }829 830 if (write && !(fd_file(f)->f_mode & FMODE_WRITE)) {831 fdput(f);832 return ERR_PTR(-EPERM);833 }834 835 fh = fd_file(f)->private_data;836 dev = fh->rc;837 838 get_device(&dev->dev);839 fdput(f);840 841 return dev;842}843 844MODULE_ALIAS("lirc_dev");845