diff -r cbfa05ad2711 linux/drivers/media/dvb/ttpci/budget-av.c --- a/linux/drivers/media/dvb/ttpci/budget-av.c Fri Aug 01 08:23:41 2008 -0300 +++ b/linux/drivers/media/dvb/ttpci/budget-av.c Sat Aug 16 06:21:58 2008 +0200 @@ -65,6 +65,7 @@ struct budget_av { struct tasklet_struct ciintf_irq_tasklet; int slot_status; struct dvb_ca_en50221 ca; + struct mutex camlock; u8 reinitialise_demod:1; }; @@ -136,6 +137,8 @@ static int ciintf_read_attribute_mem(str if (slot != 0) return -EINVAL; + mutex_lock(&budget_av->camlock); + saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); udelay(1); @@ -144,6 +147,9 @@ static int ciintf_read_attribute_mem(str ciintf_slot_shutdown(ca, slot); printk(KERN_INFO "budget-av: cam ejected 1\n"); } + + mutex_unlock(&budget_av->camlock); + return result; } @@ -155,6 +161,8 @@ static int ciintf_write_attribute_mem(st if (slot != 0) return -EINVAL; + mutex_lock(&budget_av->camlock); + saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); udelay(1); @@ -163,6 +171,9 @@ static int ciintf_write_attribute_mem(st ciintf_slot_shutdown(ca, slot); printk(KERN_INFO "budget-av: cam ejected 2\n"); } + + mutex_unlock(&budget_av->camlock); + return result; } @@ -174,6 +185,8 @@ static int ciintf_read_cam_control(struc if (slot != 0) return -EINVAL; + mutex_lock(&budget_av->camlock); + saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); udelay(1); @@ -181,8 +194,10 @@ static int ciintf_read_cam_control(struc if (result == -ETIMEDOUT) { ciintf_slot_shutdown(ca, slot); printk(KERN_INFO "budget-av: cam ejected 3\n"); - return -ETIMEDOUT; } + + mutex_unlock(&budget_av->camlock); + return result; } @@ -194,6 +209,8 @@ static int ciintf_write_cam_control(stru if (slot != 0) return -EINVAL; + mutex_lock(&budget_av->camlock); + saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); udelay(1); @@ -202,6 +219,9 @@ static int ciintf_write_cam_control(stru ciintf_slot_shutdown(ca, slot); printk(KERN_INFO "budget-av: cam ejected 5\n"); } + + mutex_unlock(&budget_av->camlock); + return result; } @@ -274,6 +294,8 @@ static int ciintf_poll_slot_status(struc if (slot != 0) return -EINVAL; + mutex_lock(&budget_av->camlock); + /* test the card detect line - needs to be done carefully * since it never goes high for some CAMs on this interface (e.g. topuptv) */ if (budget_av->slot_status == SLOTSTATUS_NONE) { @@ -304,10 +326,13 @@ static int ciintf_poll_slot_status(struc if (budget_av->slot_status != SLOTSTATUS_NONE) { ciintf_slot_shutdown(ca, slot); printk(KERN_INFO "budget-av: cam ejected 5\n"); + mutex_unlock(&budget_av->camlock); return 0; } } } + + mutex_unlock(&budget_av->camlock); /* read from attribute memory in reset/ready state to know when the CAM is ready */ if (budget_av->slot_status == SLOTSTATUS_RESET) { @@ -332,6 +357,7 @@ static int ciintf_init(struct budget_av struct saa7146_dev *saa = budget_av->budget.dev; int result; + mutex_init(&budget_av->camlock); memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221)); saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);