Commit 13f96555 authored by David Härdeman's avatar David Härdeman Committed by Mauro Carvalho Chehab

[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: default avatarDavid Härdeman <david@hardeman.nu>
Signed-off-by: default avatarSean Young <sean@mess.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent f08e5287
...@@ -99,8 +99,8 @@ struct IR { ...@@ -99,8 +99,8 @@ struct IR {
struct kref ref; struct kref ref;
struct list_head list; struct list_head list;
/* FIXME spinlock access to l.features */ /* FIXME spinlock access to l->features */
struct lirc_dev l; struct lirc_dev *l;
struct lirc_buffer rbuf; struct lirc_buffer rbuf;
struct mutex ir_lock; struct mutex ir_lock;
...@@ -184,7 +184,10 @@ static void release_ir_device(struct kref *ref) ...@@ -184,7 +184,10 @@ static void release_ir_device(struct kref *ref)
* ir->open_count == 0 - happens on final close() * ir->open_count == 0 - happens on final close()
* ir_lock, tx_ref_lock, rx_ref_lock, all released * 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)) if (kfifo_initialized(&ir->rbuf.fifo))
lirc_buffer_free(&ir->rbuf); lirc_buffer_free(&ir->rbuf);
...@@ -241,7 +244,7 @@ static void release_ir_rx(struct kref *ref) ...@@ -241,7 +244,7 @@ static void release_ir_rx(struct kref *ref)
* and releasing the ir reference can cause a sleep. That work is * and releasing the ir reference can cause a sleep. That work is
* performed by put_ir_rx() * 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 */ /* Don't put_ir_device(rx->ir) here; lock can't be freed yet */
ir->rx = NULL; ir->rx = NULL;
/* Don't do the kfree(rx) here; we still need to kill the poll thread */ /* 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) ...@@ -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_tx *tx = container_of(ref, struct IR_tx, ref);
struct IR *ir = tx->ir; 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 */ /* Don't put_ir_device(tx->ir) here, so our lock doesn't get freed */
ir->tx = NULL; ir->tx = NULL;
kfree(tx); kfree(tx);
...@@ -315,7 +318,7 @@ static int add_to_buf(struct IR *ir) ...@@ -315,7 +318,7 @@ static int add_to_buf(struct IR *ir)
int ret; int ret;
int failures = 0; int failures = 0;
unsigned char sendbuf[1] = { 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_rx *rx;
struct IR_tx *tx; struct IR_tx *tx;
...@@ -461,7 +464,7 @@ static int add_to_buf(struct IR *ir) ...@@ -461,7 +464,7 @@ static int add_to_buf(struct IR *ir)
static int lirc_thread(void *arg) static int lirc_thread(void *arg)
{ {
struct IR *ir = 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"); 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, ...@@ -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 *ir = lirc_get_pdata(filep);
struct IR_rx *rx; 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; int ret = 0, written = 0, retries = 0;
unsigned int m; unsigned int m;
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
...@@ -1200,7 +1203,7 @@ static unsigned int poll(struct file *filep, poll_table *wait) ...@@ -1200,7 +1203,7 @@ static unsigned int poll(struct file *filep, poll_table *wait)
{ {
struct IR *ir = lirc_get_pdata(filep); struct IR *ir = lirc_get_pdata(filep);
struct IR_rx *rx; struct IR_rx *rx;
struct lirc_buffer *rbuf = ir->l.rbuf; struct lirc_buffer *rbuf = ir->l->rbuf;
unsigned int ret; unsigned int ret;
dev_dbg(ir->dev, "%s called\n", __func__); dev_dbg(ir->dev, "%s called\n", __func__);
...@@ -1236,7 +1239,7 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg) ...@@ -1236,7 +1239,7 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
int result; int result;
unsigned long mode, features; unsigned long mode, features;
features = ir->l.features; features = ir->l->features;
switch (cmd) { switch (cmd) {
case LIRC_GET_LENGTH: case LIRC_GET_LENGTH:
...@@ -1346,13 +1349,6 @@ static const struct file_operations lirc_fops = { ...@@ -1346,13 +1349,6 @@ static const struct file_operations lirc_fops = {
.release = close .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) static int ir_remove(struct i2c_client *client)
{ {
if (strncmp("ir_tx_z8", client->name, 8) == 0) { if (strncmp("ir_tx_z8", client->name, 8) == 0) {
...@@ -1443,23 +1439,36 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -1443,23 +1439,36 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
spin_lock_init(&ir->rx_ref_lock); spin_lock_init(&ir->rx_ref_lock);
/* set lirc_dev stuff */ /* 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. * FIXME this is a pointer reference to us, but no refcount.
* *
* This OK for now, since lirc_dev currently won't touch this * This OK for now, since lirc_dev currently won't touch this
* buffer as we provide our own lirc_fops. * 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->rbuf = &ir->rbuf;
ir->l.dev = &adap->dev; ir->l->dev = &adap->dev;
/* This will be returned by lirc_get_pdata() */ /* This will be returned by lirc_get_pdata() */
ir->l.data = ir; ir->l->data = ir;
ret = lirc_buffer_init(ir->l.rbuf, 2, BUFLEN / 2); ret = lirc_buffer_init(ir->l->rbuf, 2, BUFLEN / 2);
if (ret) if (ret) {
lirc_free_device(ir->l);
ir->l = NULL;
goto out_put_ir; goto out_put_ir;
} }
}
if (tx_probe) { if (tx_probe) {
/* Get the IR_rx instance for later, if already allocated */ /* Get the IR_rx instance for later, if already allocated */
...@@ -1474,7 +1483,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -1474,7 +1483,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
kref_init(&tx->ref); kref_init(&tx->ref);
ir->tx = tx; ir->tx = tx;
ir->l.features |= LIRC_CAN_SEND_LIRCCODE; ir->l->features |= LIRC_CAN_SEND_LIRCCODE;
mutex_init(&tx->client_lock); mutex_init(&tx->client_lock);
tx->c = client; tx->c = client;
tx->need_boot = 1; tx->need_boot = 1;
...@@ -1518,7 +1527,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -1518,7 +1527,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
kref_init(&rx->ref); kref_init(&rx->ref);
ir->rx = rx; ir->rx = rx;
ir->l.features |= LIRC_CAN_REC_LIRCCODE; ir->l->features |= LIRC_CAN_REC_LIRCCODE;
mutex_init(&rx->client_lock); mutex_init(&rx->client_lock);
rx->c = client; rx->c = client;
rx->hdpvr_data_fmt = rx->hdpvr_data_fmt =
...@@ -1548,7 +1557,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -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 */ /* Failure exit, so put back rx ref from i2c_client */
i2c_set_clientdata(client, NULL); i2c_set_clientdata(client, NULL);
put_ir_rx(rx, true); put_ir_rx(rx, true);
ir->l.features &= ~LIRC_CAN_REC_LIRCCODE; ir->l->features &= ~LIRC_CAN_REC_LIRCCODE;
goto out_put_tx; goto out_put_tx;
} }
...@@ -1561,17 +1570,19 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -1561,17 +1570,19 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
} }
/* register with lirc */ /* register with lirc */
ret = lirc_register_device(&ir->l); ret = lirc_register_device(ir->l);
if (ret < 0) { if (ret < 0) {
dev_err(tx->ir->dev, dev_err(tx->ir->dev,
"%s: lirc_register_device() failed: %i\n", "%s: lirc_register_device() failed: %i\n",
__func__, ret); __func__, ret);
lirc_free_device(ir->l);
ir->l = NULL;
goto out_put_xx; goto out_put_xx;
} }
dev_info(ir->dev, dev_info(ir->dev,
"IR unit on %s (i2c-%d) registered as lirc%d and ready\n", "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: out_ok:
if (rx) if (rx)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment