media: lirc: create rc-core open and close lirc functions

Replace the generic kernel lirc api with ones which use rc-core, further
reducing the lirc_dev members.

Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
This commit is contained in:
Sean Young 2017-09-26 07:44:20 -04:00 committed by Mauro Carvalho Chehab
parent cb84343fce
commit 111429fb73
4 changed files with 62 additions and 78 deletions

View File

@ -88,6 +88,61 @@ void ir_lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev)
wake_up_poll(&dev->wait_poll, POLLIN | POLLRDNORM);
}
static int ir_lirc_open(struct inode *inode, struct file *file)
{
struct lirc_dev *d = container_of(inode->i_cdev, struct lirc_dev, cdev);
struct rc_dev *dev = d->rdev;
int retval;
retval = rc_open(dev);
if (retval)
return retval;
retval = mutex_lock_interruptible(&dev->lock);
if (retval)
goto out_rc;
if (!dev->registered) {
retval = -ENODEV;
goto out_unlock;
}
if (dev->lirc_open) {
retval = -EBUSY;
goto out_unlock;
}
if (dev->driver_type == RC_DRIVER_IR_RAW)
kfifo_reset_out(&dev->rawir);
dev->lirc_open++;
file->private_data = dev;
nonseekable_open(inode, file);
mutex_unlock(&dev->lock);
return 0;
out_unlock:
mutex_unlock(&dev->lock);
out_rc:
rc_close(dev);
return retval;
}
static int ir_lirc_close(struct inode *inode, struct file *file)
{
struct rc_dev *dev = file->private_data;
mutex_lock(&dev->lock);
dev->lirc_open--;
mutex_unlock(&dev->lock);
rc_close(dev);
return 0;
}
static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf,
size_t n, loff_t *ppos)
{
@ -477,8 +532,8 @@ static const struct file_operations lirc_fops = {
#endif
.read = ir_lirc_read,
.poll = ir_lirc_poll,
.open = lirc_dev_fop_open,
.release = lirc_dev_fop_close,
.open = ir_lirc_open,
.release = ir_lirc_close,
.llseek = no_llseek,
};

View File

@ -61,7 +61,6 @@ lirc_allocate_device(void)
d = kzalloc(sizeof(*d), GFP_KERNEL);
if (d) {
mutex_init(&d->mutex);
device_initialize(&d->dev);
d->dev.class = lirc_class;
d->dev.release = lirc_release_device;
@ -150,15 +149,15 @@ void lirc_unregister_device(struct lirc_dev *d)
dev_dbg(&d->dev, "lirc_dev: driver %s unregistered from minor = %d\n",
d->name, d->minor);
mutex_lock(&d->mutex);
mutex_lock(&rcdev->lock);
if (d->open) {
if (rcdev->lirc_open) {
dev_dbg(&d->dev, LOGHEAD "releasing opened driver\n",
d->name, d->minor);
wake_up_poll(&rcdev->wait_poll, POLLHUP);
}
mutex_unlock(&d->mutex);
mutex_unlock(&rcdev->lock);
cdev_device_del(&d->cdev, &d->dev);
ida_simple_remove(&lirc_ida, d->minor);
@ -166,67 +165,6 @@ void lirc_unregister_device(struct lirc_dev *d)
}
EXPORT_SYMBOL(lirc_unregister_device);
int lirc_dev_fop_open(struct inode *inode, struct file *file)
{
struct lirc_dev *d = container_of(inode->i_cdev, struct lirc_dev, cdev);
struct rc_dev *rcdev = d->rdev;
int retval;
dev_dbg(&d->dev, LOGHEAD "open called\n", d->name, d->minor);
retval = mutex_lock_interruptible(&d->mutex);
if (retval)
return retval;
if (!rcdev->registered) {
retval = -ENODEV;
goto out;
}
if (d->open) {
retval = -EBUSY;
goto out;
}
if (d->rdev) {
retval = rc_open(d->rdev);
if (retval)
goto out;
}
if (rcdev->driver_type == RC_DRIVER_IR_RAW)
kfifo_reset_out(&rcdev->rawir);
d->open++;
file->private_data = d->rdev;
nonseekable_open(inode, file);
mutex_unlock(&d->mutex);
return 0;
out:
mutex_unlock(&d->mutex);
return retval;
}
EXPORT_SYMBOL(lirc_dev_fop_open);
int lirc_dev_fop_close(struct inode *inode, struct file *file)
{
struct rc_dev *rcdev = file->private_data;
struct lirc_dev *d = rcdev->lirc_dev;
mutex_lock(&d->mutex);
rc_close(rcdev);
d->open--;
mutex_unlock(&d->mutex);
return 0;
}
EXPORT_SYMBOL(lirc_dev_fop_close);
int __init lirc_dev_init(void)
{
int retval;

View File

@ -26,8 +26,6 @@
* @rdev: &struct rc_dev associated with the device
* @fops: &struct file_operations for the device
* @owner: the module owning this struct
* @open: open count for the device's chardev
* @mutex: serialises file_operations calls
* @dev: &struct device assigned to the device
* @cdev: &struct cdev assigned to the device
*/
@ -39,10 +37,6 @@ struct lirc_dev {
const struct file_operations *fops;
struct module *owner;
int open;
struct mutex mutex; /* protect from simultaneous accesses */
struct device dev;
struct cdev cdev;
};
@ -55,9 +49,4 @@ int lirc_register_device(struct lirc_dev *d);
void lirc_unregister_device(struct lirc_dev *d);
/* default file operations
* used by drivers if they override only some operations
*/
int lirc_dev_fop_open(struct inode *inode, struct file *file);
int lirc_dev_fop_close(struct inode *inode, struct file *file);
#endif

View File

@ -117,6 +117,7 @@ enum rc_filter_type {
* @rx_resolution : resolution (in ns) of input sampler
* @tx_resolution: resolution (in ns) of output sampler
* @lirc_dev: lirc char device
* @lirc_open: count of the number of times the device has been opened
* @carrier_low: when setting the carrier range, first the low end must be
* set with an ioctl and then the high end with another ioctl
* @gap_start: time when gap starts
@ -190,6 +191,7 @@ struct rc_dev {
u32 tx_resolution;
#ifdef CONFIG_LIRC
struct lirc_dev *lirc_dev;
int lirc_open;
int carrier_low;
ktime_t gap_start;
u64 gap_duration;