static int ir_lirc_register(struct rc_dev *dev)
{
struct lirc_driver *drv;
- struct lirc_buffer *rbuf;
int rc = -ENOMEM;
unsigned long features = 0;
if (!drv)
return rc;
- rbuf = kzalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
- if (!rbuf)
- goto rbuf_alloc_failed;
-
- rc = lirc_buffer_init(rbuf, sizeof(int), LIRCBUF_SIZE);
- if (rc)
- goto rbuf_init_failed;
-
if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
features |= LIRC_CAN_REC_MODE2;
if (dev->rx_resolution)
features |= LIRC_CAN_GET_REC_RESOLUTION;
}
+
if (dev->tx_ir) {
features |= LIRC_CAN_SEND_PULSE;
if (dev->s_tx_mask)
drv->minor = -1;
drv->features = features;
drv->data = &dev->raw->lirc;
- drv->rbuf = rbuf;
+ drv->rbuf = NULL;
drv->set_use_inc = &ir_lirc_open;
drv->set_use_dec = &ir_lirc_close;
drv->code_length = sizeof(struct ir_raw_event) * 8;
+ drv->chunk_size = sizeof(int);
+ drv->buffer_size = LIRCBUF_SIZE;
drv->fops = &lirc_fops;
drv->dev = &dev->dev;
drv->rdev = dev;
drv->minor = lirc_register_driver(drv);
if (drv->minor < 0) {
rc = -ENODEV;
- goto lirc_register_failed;
+ goto out;
}
dev->raw->lirc.drv = drv;
dev->raw->lirc.dev = dev;
return 0;
-lirc_register_failed:
-rbuf_init_failed:
- kfree(rbuf);
-rbuf_alloc_failed:
+out:
kfree(drv);
-
return rc;
}
struct lirc_codec *lirc = &dev->raw->lirc;
lirc_unregister_driver(lirc->drv->minor);
- lirc_buffer_free(lirc->drv->rbuf);
- kfree(lirc->drv->rbuf);
kfree(lirc->drv);
+ lirc->drv = NULL;
return 0;
}
struct mutex irctl_lock;
struct lirc_buffer *buf;
+ bool buf_internal;
unsigned int chunk_size;
struct device dev;
put_device(ir->dev.parent);
- if (ir->buf != ir->d.rbuf) {
+ if (ir->buf_internal) {
lirc_buffer_free(ir->buf);
kfree(ir->buf);
}
if (d->rbuf) {
ir->buf = d->rbuf;
+ ir->buf_internal = false;
} else {
ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
if (!ir->buf) {
err = lirc_buffer_init(ir->buf, chunk_size, buffer_size);
if (err) {
kfree(ir->buf);
+ ir->buf = NULL;
goto out;
}
+
+ ir->buf_internal = true;
}
ir->chunk_size = ir->buf->chunk_size;
err = lirc_allocate_buffer(irctls[minor]);
if (err)
lirc_unregister_driver(minor);
+ else
+ /*
+ * This is kind of a hack but ir-lirc-codec needs
+ * access to the buffer that lirc_dev allocated.
+ */
+ d->rbuf = irctls[minor]->buf;
}
return err ? err : minor;