Commit bcbd1655 authored by Andy Walls's avatar Andy Walls Committed by Mauro Carvalho Chehab

[media] lirc_zilog: Always allocate a Rx lirc_buffer object

Always allocate a lirc_buffer object, instead of just upon setup of
the Rx i2c_client.  If we do not allocate a lirc_buffer object, because
we are not handling the Rx i2c_client, lirc_dev will allocate its own
lirc_buffer anyway and not tell us about its location.
Signed-off-by: default avatarAndy Walls <awalls@md.metrocast.net>
Signed-off-by: default avatarJarod Wilson <jarod@redhat.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 8152b760
...@@ -67,9 +67,6 @@ struct IR_rx { ...@@ -67,9 +67,6 @@ struct IR_rx {
/* RX device */ /* RX device */
struct i2c_client *c; struct i2c_client *c;
/* RX device buffer */
struct lirc_buffer buf;
/* RX polling thread data */ /* RX polling thread data */
struct task_struct *task; struct task_struct *task;
...@@ -91,6 +88,7 @@ struct IR { ...@@ -91,6 +88,7 @@ struct IR {
struct list_head list; struct list_head list;
struct lirc_driver l; struct lirc_driver l;
struct lirc_buffer rbuf;
struct mutex ir_lock; struct mutex ir_lock;
atomic_t open_count; atomic_t open_count;
...@@ -157,12 +155,13 @@ static int add_to_buf(struct IR *ir) ...@@ -157,12 +155,13 @@ 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 IR_rx *rx = ir->rx; struct IR_rx *rx = ir->rx;
if (rx == NULL) if (rx == NULL)
return -ENXIO; return -ENXIO;
if (lirc_buffer_full(&rx->buf)) { if (lirc_buffer_full(rbuf)) {
dprintk("buffer overflow\n"); dprintk("buffer overflow\n");
return -EOVERFLOW; return -EOVERFLOW;
} }
...@@ -250,9 +249,9 @@ static int add_to_buf(struct IR *ir) ...@@ -250,9 +249,9 @@ static int add_to_buf(struct IR *ir)
codes[1] = code & 0xff; codes[1] = code & 0xff;
/* return it */ /* return it */
lirc_buffer_write(&rx->buf, codes); lirc_buffer_write(rbuf, codes);
++got_data; ++got_data;
} while (!lirc_buffer_full(&rx->buf)); } while (!lirc_buffer_full(rbuf));
return 0; return 0;
} }
...@@ -270,7 +269,7 @@ static int add_to_buf(struct IR *ir) ...@@ -270,7 +269,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 IR_rx *rx = ir->rx; struct lirc_buffer *rbuf = ir->l.rbuf;
dprintk("poll thread started\n"); dprintk("poll thread started\n");
...@@ -297,7 +296,7 @@ static int lirc_thread(void *arg) ...@@ -297,7 +296,7 @@ static int lirc_thread(void *arg)
if (kthread_should_stop()) if (kthread_should_stop())
break; break;
if (!add_to_buf(ir)) if (!add_to_buf(ir))
wake_up_interruptible(&rx->buf.wait_poll); wake_up_interruptible(&rbuf->wait_poll);
} }
dprintk("poll thread ended\n"); dprintk("poll thread ended\n");
...@@ -716,6 +715,7 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) ...@@ -716,6 +715,7 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos)
{ {
struct IR *ir = filep->private_data; struct IR *ir = filep->private_data;
struct IR_rx *rx = ir->rx; struct IR_rx *rx = ir->rx;
struct lirc_buffer *rbuf = ir->l.rbuf;
int ret = 0, written = 0; int ret = 0, written = 0;
unsigned int m; unsigned int m;
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
...@@ -724,7 +724,7 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) ...@@ -724,7 +724,7 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos)
if (rx == NULL) if (rx == NULL)
return -ENODEV; return -ENODEV;
if (n % rx->buf.chunk_size) { if (n % rbuf->chunk_size) {
dprintk("read result = -EINVAL\n"); dprintk("read result = -EINVAL\n");
return -EINVAL; return -EINVAL;
} }
...@@ -734,7 +734,7 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) ...@@ -734,7 +734,7 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos)
* to avoid losing scan code (in case when queue is awaken somewhere * to avoid losing scan code (in case when queue is awaken somewhere
* between while condition checking and scheduling) * between while condition checking and scheduling)
*/ */
add_wait_queue(&rx->buf.wait_poll, &wait); add_wait_queue(&rbuf->wait_poll, &wait);
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
/* /*
...@@ -742,7 +742,7 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) ...@@ -742,7 +742,7 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos)
* mode and 'copy_to_user' is happy, wait for data. * mode and 'copy_to_user' is happy, wait for data.
*/ */
while (written < n && ret == 0) { while (written < n && ret == 0) {
if (lirc_buffer_empty(&rx->buf)) { if (lirc_buffer_empty(rbuf)) {
/* /*
* According to the read(2) man page, 'written' can be * According to the read(2) man page, 'written' can be
* returned as less than 'n', instead of blocking * returned as less than 'n', instead of blocking
...@@ -762,17 +762,17 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) ...@@ -762,17 +762,17 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos)
schedule(); schedule();
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
} else { } else {
unsigned char buf[rx->buf.chunk_size]; unsigned char buf[rbuf->chunk_size];
m = lirc_buffer_read(&rx->buf, buf); m = lirc_buffer_read(rbuf, buf);
if (m == rx->buf.chunk_size) { if (m == rbuf->chunk_size) {
ret = copy_to_user((void *)outbuf+written, buf, ret = copy_to_user((void *)outbuf+written, buf,
rx->buf.chunk_size); rbuf->chunk_size);
written += rx->buf.chunk_size; written += rbuf->chunk_size;
} }
} }
} }
remove_wait_queue(&rx->buf.wait_poll, &wait); remove_wait_queue(&rbuf->wait_poll, &wait);
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
dprintk("read result = %d (%s)\n", ret, ret ? "Error" : "OK"); dprintk("read result = %d (%s)\n", ret, ret ? "Error" : "OK");
...@@ -978,6 +978,7 @@ static unsigned int poll(struct file *filep, poll_table *wait) ...@@ -978,6 +978,7 @@ static unsigned int poll(struct file *filep, poll_table *wait)
{ {
struct IR *ir = filep->private_data; struct IR *ir = filep->private_data;
struct IR_rx *rx = ir->rx; struct IR_rx *rx = ir->rx;
struct lirc_buffer *rbuf = ir->l.rbuf;
unsigned int ret; unsigned int ret;
dprintk("poll called\n"); dprintk("poll called\n");
...@@ -995,10 +996,10 @@ static unsigned int poll(struct file *filep, poll_table *wait) ...@@ -995,10 +996,10 @@ static unsigned int poll(struct file *filep, poll_table *wait)
* Add our lirc_buffer's wait_queue to the poll_table. A wake up on * Add our lirc_buffer's wait_queue to the poll_table. A wake up on
* that buffer's wait queue indicates we may have a new poll status. * that buffer's wait queue indicates we may have a new poll status.
*/ */
poll_wait(filep, &rx->buf.wait_poll, wait); poll_wait(filep, &rbuf->wait_poll, wait);
/* Indicate what ops could happen immediately without blocking */ /* Indicate what ops could happen immediately without blocking */
ret = lirc_buffer_empty(&rx->buf) ? 0 : (POLLIN|POLLRDNORM); ret = lirc_buffer_empty(rbuf) ? 0 : (POLLIN|POLLRDNORM);
dprintk("poll result = %s\n", ret ? "POLLIN|POLLRDNORM" : "none"); dprintk("poll result = %s\n", ret ? "POLLIN|POLLRDNORM" : "none");
return ret; return ret;
...@@ -1209,8 +1210,6 @@ static int ir_remove(struct i2c_client *client) ...@@ -1209,8 +1210,6 @@ static int ir_remove(struct i2c_client *client)
/* Good-bye Rx */ /* Good-bye Rx */
destroy_rx_kthread(ir->rx); destroy_rx_kthread(ir->rx);
if (ir->rx != NULL) { if (ir->rx != NULL) {
if (ir->rx->buf.fifo_initialized)
lirc_buffer_free(&ir->rx->buf);
i2c_set_clientdata(ir->rx->c, NULL); i2c_set_clientdata(ir->rx->c, NULL);
kfree(ir->rx); kfree(ir->rx);
} }
...@@ -1222,6 +1221,8 @@ static int ir_remove(struct i2c_client *client) ...@@ -1222,6 +1221,8 @@ static int ir_remove(struct i2c_client *client)
} }
/* Good-bye IR */ /* Good-bye IR */
if (ir->rbuf.fifo_initialized)
lirc_buffer_free(&ir->rbuf);
del_ir_device(ir); del_ir_device(ir);
kfree(ir); kfree(ir);
...@@ -1292,11 +1293,17 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -1292,11 +1293,17 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
memcpy(&ir->l, &lirc_template, sizeof(struct lirc_driver)); memcpy(&ir->l, &lirc_template, sizeof(struct lirc_driver));
ir->l.minor = minor; /* module option */ ir->l.minor = minor; /* module option */
ir->l.code_length = 13; ir->l.code_length = 13;
ir->l.rbuf = NULL; ir->l.chunk_size = 2;
ir->l.buffer_size = BUFLEN / 2;
ir->l.rbuf = &ir->rbuf;
ir->l.fops = &lirc_fops; ir->l.fops = &lirc_fops;
ir->l.data = ir; ir->l.data = ir;
ir->l.dev = &adap->dev; ir->l.dev = &adap->dev;
ir->l.sample_rate = 0; ir->l.sample_rate = 0;
ret = lirc_buffer_init(ir->l.rbuf,
ir->l.chunk_size, ir->l.buffer_size);
if (ret)
goto out_free_ir;
} }
if (tx_probe) { if (tx_probe) {
...@@ -1319,16 +1326,9 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -1319,16 +1326,9 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
goto out_free_xx; goto out_free_xx;
} }
ret = lirc_buffer_init(&ir->rx->buf, 2, BUFLEN / 2);
if (ret)
goto out_free_xx;
ir->rx->c = client; ir->rx->c = client;
ir->rx->hdpvr_data_fmt = ir->rx->hdpvr_data_fmt =
(id->driver_data & ID_FLAG_HDPVR) ? true : false; (id->driver_data & ID_FLAG_HDPVR) ? true : false;
/* set lirc_dev stuff */
ir->l.rbuf = &ir->rx->buf;
} }
i2c_set_clientdata(client, ir); i2c_set_clientdata(client, ir);
...@@ -1388,8 +1388,6 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -1388,8 +1388,6 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
destroy_rx_kthread(ir->rx); destroy_rx_kthread(ir->rx);
out_free_xx: out_free_xx:
if (ir->rx != NULL) { if (ir->rx != NULL) {
if (ir->rx->buf.fifo_initialized)
lirc_buffer_free(&ir->rx->buf);
if (ir->rx->c != NULL) if (ir->rx->c != NULL)
i2c_set_clientdata(ir->rx->c, NULL); i2c_set_clientdata(ir->rx->c, NULL);
kfree(ir->rx); kfree(ir->rx);
...@@ -1399,6 +1397,8 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -1399,6 +1397,8 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
i2c_set_clientdata(ir->tx->c, NULL); i2c_set_clientdata(ir->tx->c, NULL);
kfree(ir->tx); kfree(ir->tx);
} }
if (ir->rbuf.fifo_initialized)
lirc_buffer_free(&ir->rbuf);
out_free_ir: out_free_ir:
del_ir_device(ir); del_ir_device(ir);
kfree(ir); kfree(ir);
......
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