mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-04 10:56:06 -04:00
[media] media: lirc_zilog: use a dynamically allocated lirc_dev
lirc_zilog currently embeds a struct lirc_dev in its own struct IR, but subsequent patches will make the lifetime of struct lirc_dev dynamic (i.e. it will be free():d once lirc_dev is sure there are no users of the struct). Therefore, change lirc_zilog to use a pointer to a dynamically allocated struct lirc_dev. Signed-off-by: David Härdeman <david@hardeman.nu> Signed-off-by: Sean Young <sean@mess.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
This commit is contained in:
committed by
Mauro Carvalho Chehab
parent
f08e52878e
commit
13f96555d6
@@ -99,8 +99,8 @@ struct IR {
|
||||
struct kref ref;
|
||||
struct list_head list;
|
||||
|
||||
/* FIXME spinlock access to l.features */
|
||||
struct lirc_dev l;
|
||||
/* FIXME spinlock access to l->features */
|
||||
struct lirc_dev *l;
|
||||
struct lirc_buffer rbuf;
|
||||
|
||||
struct mutex ir_lock;
|
||||
@@ -184,7 +184,10 @@ static void release_ir_device(struct kref *ref)
|
||||
* ir->open_count == 0 - happens on final close()
|
||||
* ir_lock, tx_ref_lock, rx_ref_lock, all released
|
||||
*/
|
||||
lirc_unregister_device(&ir->l);
|
||||
if (ir->l) {
|
||||
lirc_unregister_device(ir->l);
|
||||
lirc_free_device(ir->l);
|
||||
}
|
||||
|
||||
if (kfifo_initialized(&ir->rbuf.fifo))
|
||||
lirc_buffer_free(&ir->rbuf);
|
||||
@@ -241,7 +244,7 @@ static void release_ir_rx(struct kref *ref)
|
||||
* and releasing the ir reference can cause a sleep. That work is
|
||||
* performed by put_ir_rx()
|
||||
*/
|
||||
ir->l.features &= ~LIRC_CAN_REC_LIRCCODE;
|
||||
ir->l->features &= ~LIRC_CAN_REC_LIRCCODE;
|
||||
/* Don't put_ir_device(rx->ir) here; lock can't be freed yet */
|
||||
ir->rx = NULL;
|
||||
/* Don't do the kfree(rx) here; we still need to kill the poll thread */
|
||||
@@ -286,7 +289,7 @@ static void release_ir_tx(struct kref *ref)
|
||||
struct IR_tx *tx = container_of(ref, struct IR_tx, ref);
|
||||
struct IR *ir = tx->ir;
|
||||
|
||||
ir->l.features &= ~LIRC_CAN_SEND_LIRCCODE;
|
||||
ir->l->features &= ~LIRC_CAN_SEND_LIRCCODE;
|
||||
/* Don't put_ir_device(tx->ir) here, so our lock doesn't get freed */
|
||||
ir->tx = NULL;
|
||||
kfree(tx);
|
||||
@@ -315,7 +318,7 @@ static int add_to_buf(struct IR *ir)
|
||||
int ret;
|
||||
int failures = 0;
|
||||
unsigned char sendbuf[1] = { 0 };
|
||||
struct lirc_buffer *rbuf = ir->l.rbuf;
|
||||
struct lirc_buffer *rbuf = ir->l->rbuf;
|
||||
struct IR_rx *rx;
|
||||
struct IR_tx *tx;
|
||||
|
||||
@@ -461,7 +464,7 @@ static int add_to_buf(struct IR *ir)
|
||||
static int lirc_thread(void *arg)
|
||||
{
|
||||
struct IR *ir = arg;
|
||||
struct lirc_buffer *rbuf = ir->l.rbuf;
|
||||
struct lirc_buffer *rbuf = ir->l->rbuf;
|
||||
|
||||
dev_dbg(ir->dev, "poll thread started\n");
|
||||
|
||||
@@ -882,7 +885,7 @@ static ssize_t read(struct file *filep, char __user *outbuf, size_t n,
|
||||
{
|
||||
struct IR *ir = lirc_get_pdata(filep);
|
||||
struct IR_rx *rx;
|
||||
struct lirc_buffer *rbuf = ir->l.rbuf;
|
||||
struct lirc_buffer *rbuf = ir->l->rbuf;
|
||||
int ret = 0, written = 0, retries = 0;
|
||||
unsigned int m;
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
@@ -1200,7 +1203,7 @@ static unsigned int poll(struct file *filep, poll_table *wait)
|
||||
{
|
||||
struct IR *ir = lirc_get_pdata(filep);
|
||||
struct IR_rx *rx;
|
||||
struct lirc_buffer *rbuf = ir->l.rbuf;
|
||||
struct lirc_buffer *rbuf = ir->l->rbuf;
|
||||
unsigned int ret;
|
||||
|
||||
dev_dbg(ir->dev, "%s called\n", __func__);
|
||||
@@ -1236,7 +1239,7 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
|
||||
int result;
|
||||
unsigned long mode, features;
|
||||
|
||||
features = ir->l.features;
|
||||
features = ir->l->features;
|
||||
|
||||
switch (cmd) {
|
||||
case LIRC_GET_LENGTH:
|
||||
@@ -1346,13 +1349,6 @@ static const struct file_operations lirc_fops = {
|
||||
.release = close
|
||||
};
|
||||
|
||||
static struct lirc_dev lirc_template = {
|
||||
.name = "lirc_zilog",
|
||||
.code_length = 13,
|
||||
.fops = &lirc_fops,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int ir_remove(struct i2c_client *client)
|
||||
{
|
||||
if (strncmp("ir_tx_z8", client->name, 8) == 0) {
|
||||
@@ -1443,22 +1439,35 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
spin_lock_init(&ir->rx_ref_lock);
|
||||
|
||||
/* set lirc_dev stuff */
|
||||
memcpy(&ir->l, &lirc_template, sizeof(struct lirc_dev));
|
||||
ir->l = lirc_allocate_device();
|
||||
if (!ir->l) {
|
||||
ret = -ENOMEM;
|
||||
goto out_put_ir;
|
||||
}
|
||||
|
||||
snprintf(ir->l->name, sizeof(ir->l->name), "lirc_zilog");
|
||||
ir->l->code_length = 13;
|
||||
ir->l->fops = &lirc_fops;
|
||||
ir->l->owner = THIS_MODULE;
|
||||
|
||||
/*
|
||||
* FIXME this is a pointer reference to us, but no refcount.
|
||||
*
|
||||
* This OK for now, since lirc_dev currently won't touch this
|
||||
* buffer as we provide our own lirc_fops.
|
||||
*
|
||||
* Currently our own lirc_fops rely on this ir->l.rbuf pointer
|
||||
* Currently our own lirc_fops rely on this ir->l->rbuf pointer
|
||||
*/
|
||||
ir->l.rbuf = &ir->rbuf;
|
||||
ir->l.dev = &adap->dev;
|
||||
ir->l->rbuf = &ir->rbuf;
|
||||
ir->l->dev = &adap->dev;
|
||||
/* This will be returned by lirc_get_pdata() */
|
||||
ir->l.data = ir;
|
||||
ret = lirc_buffer_init(ir->l.rbuf, 2, BUFLEN / 2);
|
||||
if (ret)
|
||||
ir->l->data = ir;
|
||||
ret = lirc_buffer_init(ir->l->rbuf, 2, BUFLEN / 2);
|
||||
if (ret) {
|
||||
lirc_free_device(ir->l);
|
||||
ir->l = NULL;
|
||||
goto out_put_ir;
|
||||
}
|
||||
}
|
||||
|
||||
if (tx_probe) {
|
||||
@@ -1474,7 +1483,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
kref_init(&tx->ref);
|
||||
ir->tx = tx;
|
||||
|
||||
ir->l.features |= LIRC_CAN_SEND_LIRCCODE;
|
||||
ir->l->features |= LIRC_CAN_SEND_LIRCCODE;
|
||||
mutex_init(&tx->client_lock);
|
||||
tx->c = client;
|
||||
tx->need_boot = 1;
|
||||
@@ -1518,7 +1527,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
kref_init(&rx->ref);
|
||||
ir->rx = rx;
|
||||
|
||||
ir->l.features |= LIRC_CAN_REC_LIRCCODE;
|
||||
ir->l->features |= LIRC_CAN_REC_LIRCCODE;
|
||||
mutex_init(&rx->client_lock);
|
||||
rx->c = client;
|
||||
rx->hdpvr_data_fmt =
|
||||
@@ -1548,7 +1557,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
/* Failure exit, so put back rx ref from i2c_client */
|
||||
i2c_set_clientdata(client, NULL);
|
||||
put_ir_rx(rx, true);
|
||||
ir->l.features &= ~LIRC_CAN_REC_LIRCCODE;
|
||||
ir->l->features &= ~LIRC_CAN_REC_LIRCCODE;
|
||||
goto out_put_tx;
|
||||
}
|
||||
|
||||
@@ -1561,17 +1570,19 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
}
|
||||
|
||||
/* register with lirc */
|
||||
ret = lirc_register_device(&ir->l);
|
||||
ret = lirc_register_device(ir->l);
|
||||
if (ret < 0) {
|
||||
dev_err(tx->ir->dev,
|
||||
"%s: lirc_register_device() failed: %i\n",
|
||||
__func__, ret);
|
||||
lirc_free_device(ir->l);
|
||||
ir->l = NULL;
|
||||
goto out_put_xx;
|
||||
}
|
||||
|
||||
dev_info(ir->dev,
|
||||
"IR unit on %s (i2c-%d) registered as lirc%d and ready\n",
|
||||
adap->name, adap->nr, ir->l.minor);
|
||||
adap->name, adap->nr, ir->l->minor);
|
||||
|
||||
out_ok:
|
||||
if (rx)
|
||||
|
||||
Reference in New Issue
Block a user