* [RFC PATCH] ir-kbd-i2c, lirc_zilog: Allow bridge drivers to pass an IR trasnceiver mutex to I2C IR modules
@ 2011-01-16 3:49 Andy Walls
2011-01-16 18:27 ` Mauro Carvalho Chehab
0 siblings, 1 reply; 3+ messages in thread
From: Andy Walls @ 2011-01-16 3:49 UTC (permalink / raw)
To: Jarod Wilson, Jean Delvare, Linux Media Mailing List,
Janne Grunau, Jarod Wilson
Cc: Mauro Carvalho Chehab
The following patch allows bridge drivers, with an I2C IR Tx/Rx
transceiver, to pass a mutex for serializing access to a single I2C IR
chip between separate IR Tx and Rx modules.
The change modifies struct IR_i2c_init_data and struct IR_i2c to add
struct mutex *transceiver_lock
that ir-kbd-i2c and lirc_zilog will use, if provided by the bridge
driver. The changes to ir-kbd-i2c.[ch] and lirc_zilog.c provide the
functional change in the patch.
This patch also modifies cx18, ivtv, and hdpvr (sans Jarrod's recent
patches) to provide a transceiver_lock mutex to ir-kbd-i2c and
lirc_zilog.
I skimmed all the other modules that use IR_i2c_init_data. They all
appear to zero-fill the init_data properly before handing the data over
to ir-kbd-i2c.c.
I did find that pvrusb2 IR Rx for address 0x71 was broken, due to my
recommendation to remove automatic config for address 0x71 from
ir-kbd-i2c.c. I'll fix that in another patch, if someone with a pvrusb2
device doesn't beat me to it.
So without further ado...
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 676e5be..da1ef93 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -701,6 +701,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
mutex_init(&cx->serialize_lock);
mutex_init(&cx->gpio_lock);
+ mutex_init(&cx->ir_transceiver_lock);
mutex_init(&cx->epu2apu_mb_lock);
mutex_init(&cx->epu2cpu_mb_lock);
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index f6f3e50..82dc747 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -626,6 +626,7 @@ struct cx18 {
struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2];
struct IR_i2c_init_data ir_i2c_init_data;
+ struct mutex ir_transceiver_lock;
/* gpio */
u32 gpio_dir;
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index c330fb9..7782de1 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -96,10 +96,12 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
/* Our default information for ir-kbd-i2c.c to use */
switch (hw) {
case CX18_HW_Z8F0811_IR_RX_HAUP:
+ case CX18_HW_Z8F0811_IR_TX_HAUP:
init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
init_data->type = RC_TYPE_RC5;
init_data->name = cx->card_name;
+ init_data->transceiver_lock = &cx->ir_transceiver_lock;
info.platform_data = init_data;
break;
}
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
index f7d1ee5..df4a02a 100644
--- a/drivers/media/video/hdpvr/hdpvr-core.c
+++ b/drivers/media/video/hdpvr/hdpvr-core.c
@@ -304,6 +304,7 @@ static int hdpvr_probe(struct usb_interface *interface,
mutex_init(&dev->io_mutex);
mutex_init(&dev->i2c_mutex);
+ mutex_init(&dev->ir_transceiver_mutex);
mutex_init(&dev->usbc_mutex);
dev->usbc_buf = kmalloc(64, GFP_KERNEL);
if (!dev->usbc_buf) {
diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c
index 24966aa..b1e68b8 100644
--- a/drivers/media/video/hdpvr/hdpvr-i2c.c
+++ b/drivers/media/video/hdpvr/hdpvr-i2c.c
@@ -48,13 +48,15 @@ static int hdpvr_new_i2c_ir(struct hdpvr_device *dev, struct i2c_adapter *adap,
memset(&info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, type, I2C_NAME_SIZE);
- /* Our default information for ir-kbd-i2c.c to use */
+ /* Our default information for ir-kbd-i2c.c and lirc_zilog.c to use */
switch (addr) {
case Z8F0811_IR_RX_I2C_ADDR:
+ case Z8F0811_IR_TX_I2C_ADDR:
init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
init_data->type = RC_TYPE_RC5;
init_data->name = "HD PVR";
+ init_data->transceiver_lock = &dev->ir_transceiver_mutex;
info.platform_data = init_data;
break;
}
diff --git a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/video/hdpvr/hdpvr.h
index 37f1e4c..00c8563 100644
--- a/drivers/media/video/hdpvr/hdpvr.h
+++ b/drivers/media/video/hdpvr/hdpvr.h
@@ -112,6 +112,7 @@ struct hdpvr_device {
/* For passing data to ir-kbd-i2c */
struct IR_i2c_init_data ir_i2c_init_data;
+ struct mutex ir_transceiver_mutex;
/* usb control transfer buffer and lock */
struct mutex usbc_mutex;
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index c87b6bc..6714e1e 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -245,7 +245,15 @@ static void ir_key_poll(struct IR_i2c *ir)
int rc;
dprintk(2,"ir_poll_key\n");
+
+ if (ir->transceiver_lock)
+ mutex_lock(ir->transceiver_lock);
+
rc = ir->get_key(ir, &ir_key, &ir_raw);
+
+ if (ir->transceiver_lock)
+ mutex_unlock(ir->transceiver_lock);
+
if (rc < 0) {
dprintk(2,"error\n");
return;
@@ -362,6 +370,8 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
ir->get_key = get_key_avermedia_cardbus;
break;
}
+
+ ir->transceiver_lock = init_data->transceiver_lock;
}
if (!rc) {
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 3994642..ea2afeb 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -713,6 +713,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */
mutex_init(&itv->serialize_lock);
+ mutex_init(&itv->ir_transceiver_lock);
mutex_init(&itv->i2c_bus_lock);
mutex_init(&itv->udma.lock);
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 04bacdb..2c8d7c1 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -699,6 +699,7 @@ struct ivtv {
struct mutex i2c_bus_lock; /* lock i2c bus */
struct IR_i2c_init_data ir_i2c_init_data;
+ struct mutex ir_transceiver_lock;
/* Program Index information */
u32 pgm_info_offset; /* start of pgm info in encoder memory */
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index e103b8f..4233b48 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -184,7 +184,21 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
if (hw & IVTV_HW_IR_TX_ANY) {
if (itv->hw_flags & IVTV_HW_IR_TX_ANY)
return -1;
+
+ /* Our default information for lirc_zilog.c to use */
+ switch (hw) {
+ case IVTV_HW_Z8F0811_IR_TX_HAUP:
+ /* Default to grey remote */
+ init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
+ init_data->internal_get_key_func =
+ IR_KBD_GET_KEY_HAUP_XVR;
+ init_data->type = RC_TYPE_RC5;
+ init_data->name = itv->card_name;
+ init_data->transceiver_lock = &itv->ir_transceiver_lock;
+ break;
+ }
memset(&info, 0, sizeof(struct i2c_board_info));
+ info.platform_data = init_data;
strlcpy(info.type, type, I2C_NAME_SIZE);
return i2c_new_probed_device(adap, &info, addr_list, NULL)
== NULL ? -1 : 0;
@@ -217,6 +231,7 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
init_data->type = RC_TYPE_RC5;
init_data->name = itv->card_name;
+ init_data->transceiver_lock = &itv->ir_transceiver_lock;
break;
case IVTV_HW_I2C_IR_RX_ADAPTEC:
init_data->get_key = get_key_adaptec;
diff --git a/drivers/staging/lirc/lirc_zilog.c b/drivers/staging/lirc/lirc_zilog.c
index 18fae54..8185581 100644
--- a/drivers/staging/lirc/lirc_zilog.c
+++ b/drivers/staging/lirc/lirc_zilog.c
@@ -59,6 +59,7 @@
#include <media/lirc_dev.h>
#include <media/lirc.h>
+#include <media/ir-kbd-i2c.h>
struct IR_rx {
/* RX device */
@@ -89,6 +90,7 @@ struct IR {
struct lirc_driver l;
struct mutex ir_lock;
+ struct mutex *xcvr_lock;
int open;
struct i2c_adapter *adapter;
@@ -175,10 +177,10 @@ static int add_to_buf(struct IR *ir)
* Lock i2c bus for the duration. RX/TX chips interfere so
* this is worth it
*/
- mutex_lock(&ir->ir_lock);
+ mutex_lock(ir->xcvr_lock);
if (kthread_should_stop()) {
- mutex_unlock(&ir->ir_lock);
+ mutex_unlock(ir->xcvr_lock);
return -ENODATA;
}
@@ -190,7 +192,7 @@ static int add_to_buf(struct IR *ir)
if (ret != 1) {
zilog_error("i2c_master_send failed with %d\n", ret);
if (failures >= 3) {
- mutex_unlock(&ir->ir_lock);
+ mutex_unlock(ir->xcvr_lock);
zilog_error("unable to read from the IR chip "
"after 3 resets, giving up\n");
return ret;
@@ -202,23 +204,23 @@ static int add_to_buf(struct IR *ir)
set_current_state(TASK_UNINTERRUPTIBLE);
if (kthread_should_stop()) {
- mutex_unlock(&ir->ir_lock);
+ mutex_unlock(ir->xcvr_lock);
return -ENODATA;
}
schedule_timeout((100 * HZ + 999) / 1000);
ir->tx->need_boot = 1;
++failures;
- mutex_unlock(&ir->ir_lock);
+ mutex_unlock(ir->xcvr_lock);
continue;
}
if (kthread_should_stop()) {
- mutex_unlock(&ir->ir_lock);
+ mutex_unlock(ir->xcvr_lock);
return -ENODATA;
}
ret = i2c_master_recv(rx->c, keybuf, sizeof(keybuf));
- mutex_unlock(&ir->ir_lock);
+ mutex_unlock(ir->xcvr_lock);
if (ret != sizeof(keybuf)) {
zilog_error("i2c_master_recv failed with %d -- "
"keeping last read buffer\n", ret);
@@ -920,7 +922,7 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
return -EINVAL;
/* Lock i2c bus for the duration */
- mutex_lock(&ir->ir_lock);
+ mutex_lock(ir->xcvr_lock);
/* Send each keypress */
for (i = 0; i < n;) {
@@ -928,7 +930,7 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
int command;
if (copy_from_user(&command, buf + i, sizeof(command))) {
- mutex_unlock(&ir->ir_lock);
+ mutex_unlock(ir->xcvr_lock);
return -EFAULT;
}
@@ -944,7 +946,7 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
ret = send_code(tx, (unsigned)command >> 16,
(unsigned)command & 0xFFFF);
if (ret == -EPROTO) {
- mutex_unlock(&ir->ir_lock);
+ mutex_unlock(ir->xcvr_lock);
return ret;
}
}
@@ -961,7 +963,7 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
if (failures >= 3) {
zilog_error("unable to send to the IR chip "
"after 3 resets, giving up\n");
- mutex_unlock(&ir->ir_lock);
+ mutex_unlock(ir->xcvr_lock);
return ret;
}
set_current_state(TASK_UNINTERRUPTIBLE);
@@ -973,7 +975,7 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
}
/* Release i2c bus */
- mutex_unlock(&ir->ir_lock);
+ mutex_unlock(ir->xcvr_lock);
/* All looks good */
return n;
@@ -1079,15 +1081,15 @@ static int open(struct inode *node, struct file *filep)
return -ENODEV;
/* increment in use count */
- mutex_lock(&ir->ir_lock);
+ mutex_lock(ir->xcvr_lock);
++ir->open;
ret = set_use_inc(ir);
if (ret != 0) {
--ir->open;
- mutex_unlock(&ir->ir_lock);
+ mutex_unlock(ir->xcvr_lock);
return ret;
}
- mutex_unlock(&ir->ir_lock);
+ mutex_unlock(ir->xcvr_lock);
/* stash our IR struct */
filep->private_data = ir;
@@ -1106,10 +1108,10 @@ static int close(struct inode *node, struct file *filep)
}
/* decrement in use count */
- mutex_lock(&ir->ir_lock);
+ mutex_lock(ir->xcvr_lock);
--ir->open;
set_use_dec(ir);
- mutex_unlock(&ir->ir_lock);
+ mutex_unlock(ir->xcvr_lock);
return 0;
}
@@ -1251,6 +1253,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct IR *ir;
struct i2c_adapter *adap = client->adapter;
+ const struct IR_i2c_init_data *init_data = client->dev.platform_data;
int ret;
bool tx_probe = false;
@@ -1288,6 +1291,12 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
ir->adapter = adap;
mutex_init(&ir->ir_lock);
+ /* Use bridge driver's transceiver lock, if provided */
+ if (init_data != NULL)
+ ir->xcvr_lock = init_data->transceiver_lock;
+ if (ir->xcvr_lock == NULL)
+ ir->xcvr_lock = &ir->ir_lock;
+
/* set lirc_dev stuff */
memcpy(&ir->l, &lirc_template, sizeof(struct lirc_driver));
ir->l.minor = minor; /* module option */
diff --git a/include/media/ir-kbd-i2c.h b/include/media/ir-kbd-i2c.h
index 768aa77..5893fd8 100644
--- a/include/media/ir-kbd-i2c.h
+++ b/include/media/ir-kbd-i2c.h
@@ -21,6 +21,7 @@ struct IR_i2c {
char name[32];
char phys[32];
int (*get_key)(struct IR_i2c*, u32*, u32*);
+ struct mutex *transceiver_lock;
};
enum ir_kbd_get_key_fn {
@@ -48,5 +49,7 @@ struct IR_i2c_init_data {
enum ir_kbd_get_key_fn internal_get_key_func;
struct rc_dev *rc_dev;
+
+ struct mutex *transceiver_lock;
};
#endif
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [RFC PATCH] ir-kbd-i2c, lirc_zilog: Allow bridge drivers to pass an IR trasnceiver mutex to I2C IR modules
2011-01-16 3:49 [RFC PATCH] ir-kbd-i2c, lirc_zilog: Allow bridge drivers to pass an IR trasnceiver mutex to I2C IR modules Andy Walls
@ 2011-01-16 18:27 ` Mauro Carvalho Chehab
2011-01-16 19:29 ` Andy Walls
0 siblings, 1 reply; 3+ messages in thread
From: Mauro Carvalho Chehab @ 2011-01-16 18:27 UTC (permalink / raw)
To: Andy Walls
Cc: Jarod Wilson, Jean Delvare, Linux Media Mailing List,
Janne Grunau, Jarod Wilson
Jarod/Andy,
For now, I'm marking all those ir-kbd-i2c/lirc_zilog patches as "RFC" at patchwork,
as I'm not sure if they're ok, and because there are a few revisions of them and
I'm afraid to apply some wrong version.
Please, after finishing and testing, send me a patch series or, preferably, a
git pull with those stuff.
Thanks!
Mauro
Em 16-01-2011 01:49, Andy Walls escreveu:
> The following patch allows bridge drivers, with an I2C IR Tx/Rx
> transceiver, to pass a mutex for serializing access to a single I2C IR
> chip between separate IR Tx and Rx modules.
>
> The change modifies struct IR_i2c_init_data and struct IR_i2c to add
>
> struct mutex *transceiver_lock
>
> that ir-kbd-i2c and lirc_zilog will use, if provided by the bridge
> driver. The changes to ir-kbd-i2c.[ch] and lirc_zilog.c provide the
> functional change in the patch.
>
> This patch also modifies cx18, ivtv, and hdpvr (sans Jarrod's recent
> patches) to provide a transceiver_lock mutex to ir-kbd-i2c and
> lirc_zilog.
>
> I skimmed all the other modules that use IR_i2c_init_data. They all
> appear to zero-fill the init_data properly before handing the data over
> to ir-kbd-i2c.c.
>
> I did find that pvrusb2 IR Rx for address 0x71 was broken, due to my
> recommendation to remove automatic config for address 0x71 from
> ir-kbd-i2c.c. I'll fix that in another patch, if someone with a pvrusb2
> device doesn't beat me to it.
>
> So without further ado...
>
>
> diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
> index 676e5be..da1ef93 100644
> --- a/drivers/media/video/cx18/cx18-driver.c
> +++ b/drivers/media/video/cx18/cx18-driver.c
> @@ -701,6 +701,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
>
> mutex_init(&cx->serialize_lock);
> mutex_init(&cx->gpio_lock);
> + mutex_init(&cx->ir_transceiver_lock);
> mutex_init(&cx->epu2apu_mb_lock);
> mutex_init(&cx->epu2cpu_mb_lock);
>
> diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
> index f6f3e50..82dc747 100644
> --- a/drivers/media/video/cx18/cx18-driver.h
> +++ b/drivers/media/video/cx18/cx18-driver.h
> @@ -626,6 +626,7 @@ struct cx18 {
> struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2];
>
> struct IR_i2c_init_data ir_i2c_init_data;
> + struct mutex ir_transceiver_lock;
>
> /* gpio */
> u32 gpio_dir;
> diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
> index c330fb9..7782de1 100644
> --- a/drivers/media/video/cx18/cx18-i2c.c
> +++ b/drivers/media/video/cx18/cx18-i2c.c
> @@ -96,10 +96,12 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
> /* Our default information for ir-kbd-i2c.c to use */
> switch (hw) {
> case CX18_HW_Z8F0811_IR_RX_HAUP:
> + case CX18_HW_Z8F0811_IR_TX_HAUP:
> init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
> init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
> init_data->type = RC_TYPE_RC5;
> init_data->name = cx->card_name;
> + init_data->transceiver_lock = &cx->ir_transceiver_lock;
> info.platform_data = init_data;
> break;
> }
> diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
> index f7d1ee5..df4a02a 100644
> --- a/drivers/media/video/hdpvr/hdpvr-core.c
> +++ b/drivers/media/video/hdpvr/hdpvr-core.c
> @@ -304,6 +304,7 @@ static int hdpvr_probe(struct usb_interface *interface,
>
> mutex_init(&dev->io_mutex);
> mutex_init(&dev->i2c_mutex);
> + mutex_init(&dev->ir_transceiver_mutex);
> mutex_init(&dev->usbc_mutex);
> dev->usbc_buf = kmalloc(64, GFP_KERNEL);
> if (!dev->usbc_buf) {
> diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c
> index 24966aa..b1e68b8 100644
> --- a/drivers/media/video/hdpvr/hdpvr-i2c.c
> +++ b/drivers/media/video/hdpvr/hdpvr-i2c.c
> @@ -48,13 +48,15 @@ static int hdpvr_new_i2c_ir(struct hdpvr_device *dev, struct i2c_adapter *adap,
> memset(&info, 0, sizeof(struct i2c_board_info));
> strlcpy(info.type, type, I2C_NAME_SIZE);
>
> - /* Our default information for ir-kbd-i2c.c to use */
> + /* Our default information for ir-kbd-i2c.c and lirc_zilog.c to use */
> switch (addr) {
> case Z8F0811_IR_RX_I2C_ADDR:
> + case Z8F0811_IR_TX_I2C_ADDR:
> init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
> init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
> init_data->type = RC_TYPE_RC5;
> init_data->name = "HD PVR";
> + init_data->transceiver_lock = &dev->ir_transceiver_mutex;
> info.platform_data = init_data;
> break;
> }
> diff --git a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/video/hdpvr/hdpvr.h
> index 37f1e4c..00c8563 100644
> --- a/drivers/media/video/hdpvr/hdpvr.h
> +++ b/drivers/media/video/hdpvr/hdpvr.h
> @@ -112,6 +112,7 @@ struct hdpvr_device {
>
> /* For passing data to ir-kbd-i2c */
> struct IR_i2c_init_data ir_i2c_init_data;
> + struct mutex ir_transceiver_mutex;
>
> /* usb control transfer buffer and lock */
> struct mutex usbc_mutex;
> diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
> index c87b6bc..6714e1e 100644
> --- a/drivers/media/video/ir-kbd-i2c.c
> +++ b/drivers/media/video/ir-kbd-i2c.c
> @@ -245,7 +245,15 @@ static void ir_key_poll(struct IR_i2c *ir)
> int rc;
>
> dprintk(2,"ir_poll_key\n");
> +
> + if (ir->transceiver_lock)
> + mutex_lock(ir->transceiver_lock);
> +
> rc = ir->get_key(ir, &ir_key, &ir_raw);
> +
> + if (ir->transceiver_lock)
> + mutex_unlock(ir->transceiver_lock);
> +
> if (rc < 0) {
> dprintk(2,"error\n");
> return;
> @@ -362,6 +370,8 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
> ir->get_key = get_key_avermedia_cardbus;
> break;
> }
> +
> + ir->transceiver_lock = init_data->transceiver_lock;
> }
>
> if (!rc) {
> diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
> index 3994642..ea2afeb 100644
> --- a/drivers/media/video/ivtv/ivtv-driver.c
> +++ b/drivers/media/video/ivtv/ivtv-driver.c
> @@ -713,6 +713,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
> itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */
>
> mutex_init(&itv->serialize_lock);
> + mutex_init(&itv->ir_transceiver_lock);
> mutex_init(&itv->i2c_bus_lock);
> mutex_init(&itv->udma.lock);
>
> diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
> index 04bacdb..2c8d7c1 100644
> --- a/drivers/media/video/ivtv/ivtv-driver.h
> +++ b/drivers/media/video/ivtv/ivtv-driver.h
> @@ -699,6 +699,7 @@ struct ivtv {
> struct mutex i2c_bus_lock; /* lock i2c bus */
>
> struct IR_i2c_init_data ir_i2c_init_data;
> + struct mutex ir_transceiver_lock;
>
> /* Program Index information */
> u32 pgm_info_offset; /* start of pgm info in encoder memory */
> diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
> index e103b8f..4233b48 100644
> --- a/drivers/media/video/ivtv/ivtv-i2c.c
> +++ b/drivers/media/video/ivtv/ivtv-i2c.c
> @@ -184,7 +184,21 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
> if (hw & IVTV_HW_IR_TX_ANY) {
> if (itv->hw_flags & IVTV_HW_IR_TX_ANY)
> return -1;
> +
> + /* Our default information for lirc_zilog.c to use */
> + switch (hw) {
> + case IVTV_HW_Z8F0811_IR_TX_HAUP:
> + /* Default to grey remote */
> + init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
> + init_data->internal_get_key_func =
> + IR_KBD_GET_KEY_HAUP_XVR;
> + init_data->type = RC_TYPE_RC5;
> + init_data->name = itv->card_name;
> + init_data->transceiver_lock = &itv->ir_transceiver_lock;
> + break;
> + }
> memset(&info, 0, sizeof(struct i2c_board_info));
> + info.platform_data = init_data;
> strlcpy(info.type, type, I2C_NAME_SIZE);
> return i2c_new_probed_device(adap, &info, addr_list, NULL)
> == NULL ? -1 : 0;
> @@ -217,6 +231,7 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
> init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
> init_data->type = RC_TYPE_RC5;
> init_data->name = itv->card_name;
> + init_data->transceiver_lock = &itv->ir_transceiver_lock;
> break;
> case IVTV_HW_I2C_IR_RX_ADAPTEC:
> init_data->get_key = get_key_adaptec;
> diff --git a/drivers/staging/lirc/lirc_zilog.c b/drivers/staging/lirc/lirc_zilog.c
> index 18fae54..8185581 100644
> --- a/drivers/staging/lirc/lirc_zilog.c
> +++ b/drivers/staging/lirc/lirc_zilog.c
> @@ -59,6 +59,7 @@
>
> #include <media/lirc_dev.h>
> #include <media/lirc.h>
> +#include <media/ir-kbd-i2c.h>
>
> struct IR_rx {
> /* RX device */
> @@ -89,6 +90,7 @@ struct IR {
> struct lirc_driver l;
>
> struct mutex ir_lock;
> + struct mutex *xcvr_lock;
> int open;
>
> struct i2c_adapter *adapter;
> @@ -175,10 +177,10 @@ static int add_to_buf(struct IR *ir)
> * Lock i2c bus for the duration. RX/TX chips interfere so
> * this is worth it
> */
> - mutex_lock(&ir->ir_lock);
> + mutex_lock(ir->xcvr_lock);
>
> if (kthread_should_stop()) {
> - mutex_unlock(&ir->ir_lock);
> + mutex_unlock(ir->xcvr_lock);
> return -ENODATA;
> }
>
> @@ -190,7 +192,7 @@ static int add_to_buf(struct IR *ir)
> if (ret != 1) {
> zilog_error("i2c_master_send failed with %d\n", ret);
> if (failures >= 3) {
> - mutex_unlock(&ir->ir_lock);
> + mutex_unlock(ir->xcvr_lock);
> zilog_error("unable to read from the IR chip "
> "after 3 resets, giving up\n");
> return ret;
> @@ -202,23 +204,23 @@ static int add_to_buf(struct IR *ir)
>
> set_current_state(TASK_UNINTERRUPTIBLE);
> if (kthread_should_stop()) {
> - mutex_unlock(&ir->ir_lock);
> + mutex_unlock(ir->xcvr_lock);
> return -ENODATA;
> }
> schedule_timeout((100 * HZ + 999) / 1000);
> ir->tx->need_boot = 1;
>
> ++failures;
> - mutex_unlock(&ir->ir_lock);
> + mutex_unlock(ir->xcvr_lock);
> continue;
> }
>
> if (kthread_should_stop()) {
> - mutex_unlock(&ir->ir_lock);
> + mutex_unlock(ir->xcvr_lock);
> return -ENODATA;
> }
> ret = i2c_master_recv(rx->c, keybuf, sizeof(keybuf));
> - mutex_unlock(&ir->ir_lock);
> + mutex_unlock(ir->xcvr_lock);
> if (ret != sizeof(keybuf)) {
> zilog_error("i2c_master_recv failed with %d -- "
> "keeping last read buffer\n", ret);
> @@ -920,7 +922,7 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
> return -EINVAL;
>
> /* Lock i2c bus for the duration */
> - mutex_lock(&ir->ir_lock);
> + mutex_lock(ir->xcvr_lock);
>
> /* Send each keypress */
> for (i = 0; i < n;) {
> @@ -928,7 +930,7 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
> int command;
>
> if (copy_from_user(&command, buf + i, sizeof(command))) {
> - mutex_unlock(&ir->ir_lock);
> + mutex_unlock(ir->xcvr_lock);
> return -EFAULT;
> }
>
> @@ -944,7 +946,7 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
> ret = send_code(tx, (unsigned)command >> 16,
> (unsigned)command & 0xFFFF);
> if (ret == -EPROTO) {
> - mutex_unlock(&ir->ir_lock);
> + mutex_unlock(ir->xcvr_lock);
> return ret;
> }
> }
> @@ -961,7 +963,7 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
> if (failures >= 3) {
> zilog_error("unable to send to the IR chip "
> "after 3 resets, giving up\n");
> - mutex_unlock(&ir->ir_lock);
> + mutex_unlock(ir->xcvr_lock);
> return ret;
> }
> set_current_state(TASK_UNINTERRUPTIBLE);
> @@ -973,7 +975,7 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
> }
>
> /* Release i2c bus */
> - mutex_unlock(&ir->ir_lock);
> + mutex_unlock(ir->xcvr_lock);
>
> /* All looks good */
> return n;
> @@ -1079,15 +1081,15 @@ static int open(struct inode *node, struct file *filep)
> return -ENODEV;
>
> /* increment in use count */
> - mutex_lock(&ir->ir_lock);
> + mutex_lock(ir->xcvr_lock);
> ++ir->open;
> ret = set_use_inc(ir);
> if (ret != 0) {
> --ir->open;
> - mutex_unlock(&ir->ir_lock);
> + mutex_unlock(ir->xcvr_lock);
> return ret;
> }
> - mutex_unlock(&ir->ir_lock);
> + mutex_unlock(ir->xcvr_lock);
>
> /* stash our IR struct */
> filep->private_data = ir;
> @@ -1106,10 +1108,10 @@ static int close(struct inode *node, struct file *filep)
> }
>
> /* decrement in use count */
> - mutex_lock(&ir->ir_lock);
> + mutex_lock(ir->xcvr_lock);
> --ir->open;
> set_use_dec(ir);
> - mutex_unlock(&ir->ir_lock);
> + mutex_unlock(ir->xcvr_lock);
>
> return 0;
> }
> @@ -1251,6 +1253,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
> {
> struct IR *ir;
> struct i2c_adapter *adap = client->adapter;
> + const struct IR_i2c_init_data *init_data = client->dev.platform_data;
> int ret;
> bool tx_probe = false;
>
> @@ -1288,6 +1291,12 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
> ir->adapter = adap;
> mutex_init(&ir->ir_lock);
>
> + /* Use bridge driver's transceiver lock, if provided */
> + if (init_data != NULL)
> + ir->xcvr_lock = init_data->transceiver_lock;
> + if (ir->xcvr_lock == NULL)
> + ir->xcvr_lock = &ir->ir_lock;
> +
> /* set lirc_dev stuff */
> memcpy(&ir->l, &lirc_template, sizeof(struct lirc_driver));
> ir->l.minor = minor; /* module option */
> diff --git a/include/media/ir-kbd-i2c.h b/include/media/ir-kbd-i2c.h
> index 768aa77..5893fd8 100644
> --- a/include/media/ir-kbd-i2c.h
> +++ b/include/media/ir-kbd-i2c.h
> @@ -21,6 +21,7 @@ struct IR_i2c {
> char name[32];
> char phys[32];
> int (*get_key)(struct IR_i2c*, u32*, u32*);
> + struct mutex *transceiver_lock;
> };
>
> enum ir_kbd_get_key_fn {
> @@ -48,5 +49,7 @@ struct IR_i2c_init_data {
> enum ir_kbd_get_key_fn internal_get_key_func;
>
> struct rc_dev *rc_dev;
> +
> + struct mutex *transceiver_lock;
> };
> #endif
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [RFC PATCH] ir-kbd-i2c, lirc_zilog: Allow bridge drivers to pass an IR trasnceiver mutex to I2C IR modules
2011-01-16 18:27 ` Mauro Carvalho Chehab
@ 2011-01-16 19:29 ` Andy Walls
0 siblings, 0 replies; 3+ messages in thread
From: Andy Walls @ 2011-01-16 19:29 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: Jarod Wilson, Jean Delvare, Linux Media Mailing List,
Janne Grunau, Jarod Wilson
On Sun, 2011-01-16 at 16:27 -0200, Mauro Carvalho Chehab wrote:
> Jarod/Andy,
>
> For now, I'm marking all those ir-kbd-i2c/lirc_zilog patches as "RFC" at patchwork,
> as I'm not sure if they're ok, and because there are a few revisions of them and
> I'm afraid to apply some wrong version.
And that's just fine. :)
That particular RFC was to get mostly Jean's opinion on adding fields to
struct IR_i2c_init_data and struct IR_i2c and code to ir-kbd-i2c.
> Please, after finishing and testing, send me a patch series or, preferably, a
> git pull with those stuff.
I just sent a [GIT PATCHES for 2.6.38], which is my pull request. It
fixes one minor regression in ir-kbd-i2c.c. The rest of the patches are
limited to lirc_zilog and do not modify any bridge drivers. The
lirc_zilog changes were tested by me using my HVR-1600.
Jarrod will have to ask you to pull any hdpvr fixes, when he feels they
are ready.
Note my pull request does *not* include the patches in the subject [RFC
PATCH], so no worries about pulling those in. :) I'll submit a pull for
those when they are correct and ready.
Regards,
Andy
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2011-01-16 19:29 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-01-16 3:49 [RFC PATCH] ir-kbd-i2c, lirc_zilog: Allow bridge drivers to pass an IR trasnceiver mutex to I2C IR modules Andy Walls
2011-01-16 18:27 ` Mauro Carvalho Chehab
2011-01-16 19:29 ` Andy Walls
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox