mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-11 14:26:40 +07:00
[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: Andy Walls <awalls@md.metrocast.net> Signed-off-by: Jarod Wilson <jarod@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
8152b760ef
commit
bcbd165509
@ -67,9 +67,6 @@ struct IR_rx {
|
||||
/* RX device */
|
||||
struct i2c_client *c;
|
||||
|
||||
/* RX device buffer */
|
||||
struct lirc_buffer buf;
|
||||
|
||||
/* RX polling thread data */
|
||||
struct task_struct *task;
|
||||
|
||||
@ -91,6 +88,7 @@ struct IR {
|
||||
struct list_head list;
|
||||
|
||||
struct lirc_driver l;
|
||||
struct lirc_buffer rbuf;
|
||||
|
||||
struct mutex ir_lock;
|
||||
atomic_t open_count;
|
||||
@ -157,12 +155,13 @@ 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 IR_rx *rx = ir->rx;
|
||||
|
||||
if (rx == NULL)
|
||||
return -ENXIO;
|
||||
|
||||
if (lirc_buffer_full(&rx->buf)) {
|
||||
if (lirc_buffer_full(rbuf)) {
|
||||
dprintk("buffer overflow\n");
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
@ -250,9 +249,9 @@ static int add_to_buf(struct IR *ir)
|
||||
codes[1] = code & 0xff;
|
||||
|
||||
/* return it */
|
||||
lirc_buffer_write(&rx->buf, codes);
|
||||
lirc_buffer_write(rbuf, codes);
|
||||
++got_data;
|
||||
} while (!lirc_buffer_full(&rx->buf));
|
||||
} while (!lirc_buffer_full(rbuf));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -270,7 +269,7 @@ static int add_to_buf(struct IR *ir)
|
||||
static int lirc_thread(void *arg)
|
||||
{
|
||||
struct IR *ir = arg;
|
||||
struct IR_rx *rx = ir->rx;
|
||||
struct lirc_buffer *rbuf = ir->l.rbuf;
|
||||
|
||||
dprintk("poll thread started\n");
|
||||
|
||||
@ -297,7 +296,7 @@ static int lirc_thread(void *arg)
|
||||
if (kthread_should_stop())
|
||||
break;
|
||||
if (!add_to_buf(ir))
|
||||
wake_up_interruptible(&rx->buf.wait_poll);
|
||||
wake_up_interruptible(&rbuf->wait_poll);
|
||||
}
|
||||
|
||||
dprintk("poll thread ended\n");
|
||||
@ -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_rx *rx = ir->rx;
|
||||
struct lirc_buffer *rbuf = ir->l.rbuf;
|
||||
int ret = 0, written = 0;
|
||||
unsigned int m;
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
@ -724,7 +724,7 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos)
|
||||
if (rx == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
if (n % rx->buf.chunk_size) {
|
||||
if (n % rbuf->chunk_size) {
|
||||
dprintk("read result = -EINVAL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -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
|
||||
* 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);
|
||||
|
||||
/*
|
||||
@ -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.
|
||||
*/
|
||||
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
|
||||
* 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)
|
||||
schedule();
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
} else {
|
||||
unsigned char buf[rx->buf.chunk_size];
|
||||
m = lirc_buffer_read(&rx->buf, buf);
|
||||
if (m == rx->buf.chunk_size) {
|
||||
unsigned char buf[rbuf->chunk_size];
|
||||
m = lirc_buffer_read(rbuf, buf);
|
||||
if (m == rbuf->chunk_size) {
|
||||
ret = copy_to_user((void *)outbuf+written, buf,
|
||||
rx->buf.chunk_size);
|
||||
written += rx->buf.chunk_size;
|
||||
rbuf->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);
|
||||
|
||||
dprintk("read result = %d (%s)\n", ret, ret ? "Error" : "OK");
|
||||
@ -978,6 +978,7 @@ static unsigned int poll(struct file *filep, poll_table *wait)
|
||||
{
|
||||
struct IR *ir = filep->private_data;
|
||||
struct IR_rx *rx = ir->rx;
|
||||
struct lirc_buffer *rbuf = ir->l.rbuf;
|
||||
unsigned int ret;
|
||||
|
||||
dprintk("poll called\n");
|
||||
@ -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
|
||||
* 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 */
|
||||
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");
|
||||
return ret;
|
||||
@ -1209,8 +1210,6 @@ static int ir_remove(struct i2c_client *client)
|
||||
/* Good-bye Rx */
|
||||
destroy_rx_kthread(ir->rx);
|
||||
if (ir->rx != NULL) {
|
||||
if (ir->rx->buf.fifo_initialized)
|
||||
lirc_buffer_free(&ir->rx->buf);
|
||||
i2c_set_clientdata(ir->rx->c, NULL);
|
||||
kfree(ir->rx);
|
||||
}
|
||||
@ -1222,6 +1221,8 @@ static int ir_remove(struct i2c_client *client)
|
||||
}
|
||||
|
||||
/* Good-bye IR */
|
||||
if (ir->rbuf.fifo_initialized)
|
||||
lirc_buffer_free(&ir->rbuf);
|
||||
del_ir_device(ir);
|
||||
kfree(ir);
|
||||
|
||||
@ -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));
|
||||
ir->l.minor = minor; /* module option */
|
||||
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.data = ir;
|
||||
ir->l.dev = &adap->dev;
|
||||
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) {
|
||||
@ -1319,16 +1326,9 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
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->hdpvr_data_fmt =
|
||||
(id->driver_data & ID_FLAG_HDPVR) ? true : false;
|
||||
|
||||
/* set lirc_dev stuff */
|
||||
ir->l.rbuf = &ir->rx->buf;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, ir);
|
||||
@ -1388,8 +1388,6 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
destroy_rx_kthread(ir->rx);
|
||||
out_free_xx:
|
||||
if (ir->rx != NULL) {
|
||||
if (ir->rx->buf.fifo_initialized)
|
||||
lirc_buffer_free(&ir->rx->buf);
|
||||
if (ir->rx->c != NULL)
|
||||
i2c_set_clientdata(ir->rx->c, NULL);
|
||||
kfree(ir->rx);
|
||||
@ -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);
|
||||
kfree(ir->tx);
|
||||
}
|
||||
if (ir->rbuf.fifo_initialized)
|
||||
lirc_buffer_free(&ir->rbuf);
|
||||
out_free_ir:
|
||||
del_ir_device(ir);
|
||||
kfree(ir);
|
||||
|
Loading…
Reference in New Issue
Block a user