summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
authorAndrew de Quincy <devnull@localhost>2004-11-12 15:54:49 +0000
committerAndrew de Quincy <devnull@localhost>2004-11-12 15:54:49 +0000
commit1f6bbb618acf46deff76b1a84836656b9db99b2a (patch)
treea46d61da5cab9ce90fc14167677aef76f86654b5 /linux
parent6619ffef1ac825f47ff0ac16eecfa0225bdc7f2a (diff)
downloadmediapointer-dvb-s2-1f6bbb618acf46deff76b1a84836656b9db99b2a.tar.gz
mediapointer-dvb-s2-1f6bbb618acf46deff76b1a84836656b9db99b2a.tar.bz2
Added locking to prevent GPIO problem between polling and IO/attribute memory
access
Diffstat (limited to 'linux')
-rw-r--r--linux/drivers/media/dvb/ttpci/budget-av.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/linux/drivers/media/dvb/ttpci/budget-av.c b/linux/drivers/media/dvb/ttpci/budget-av.c
index 1cf473d13..0a6f44e6d 100644
--- a/linux/drivers/media/dvb/ttpci/budget-av.c
+++ b/linux/drivers/media/dvb/ttpci/budget-av.c
@@ -57,6 +57,7 @@ struct budget_av {
struct tasklet_struct ciintf_irq_tasklet;
int slot_status;
struct dvb_ca_en50221 ca;
+ spinlock_t gpiolock;
};
int enable_ci = 0;
@@ -117,48 +118,64 @@ static int ciintf_read_attribute_mem (struct dvb_ca_en50221 *ca, int slot,
int address)
{
struct budget_av *budget_av = (struct budget_av *) ca->data;
+ int result;
if (slot != 0)
return -EINVAL;
+ spin_lock(&budget_av->gpiolock);
saa7146_setgpio (budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
- return ttpci_budget_debiread (&budget_av->budget, DEBICICAM, address & 0xfff, 1);
+ result = ttpci_budget_debiread (&budget_av->budget, DEBICICAM, address & 0xfff, 1);
+ spin_unlock(&budget_av->gpiolock);
+ return result;
}
static int ciintf_write_attribute_mem (struct dvb_ca_en50221 *ca, int slot,
int address, u8 value)
{
struct budget_av *budget_av = (struct budget_av *) ca->data;
+ int result;
if (slot != 0)
return -EINVAL;
+ spin_lock(&budget_av->gpiolock);
saa7146_setgpio (budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
- return ttpci_budget_debiwrite (&budget_av->budget, DEBICICAM, address & 0xfff, 1, value);
+ result = ttpci_budget_debiwrite (&budget_av->budget, DEBICICAM, address & 0xfff, 1, value);
+ spin_unlock(&budget_av->gpiolock);
+ return result;
}
static int ciintf_read_cam_control (struct dvb_ca_en50221 *ca, int slot,
u8 address)
{
struct budget_av *budget_av = (struct budget_av *) ca->data;
+ int result;
if (slot != 0)
return -EINVAL;
+ spin_lock(&budget_av->gpiolock);
saa7146_setgpio (budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
- return ttpci_budget_debiread (&budget_av->budget, DEBICICAM, address & 3, 1);
+ result = ttpci_budget_debiread (&budget_av->budget, DEBICICAM, address & 3, 1);
+ spin_unlock(&budget_av->gpiolock);
+ return result;
}
static int ciintf_write_cam_control (struct dvb_ca_en50221 *ca, int slot,
u8 address, u8 value)
{
struct budget_av *budget_av = (struct budget_av *) ca->data;
+ int result;
if (slot != 0)
return -EINVAL;
+ spin_lock(&budget_av->gpiolock);
saa7146_setgpio (budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
- return ttpci_budget_debiwrite (&budget_av->budget, DEBICICAM, address & 3, 1, value);
+ result = ttpci_budget_debiwrite (&budget_av->budget, DEBICICAM, address & 3, 1, value);
+ spin_unlock(&budget_av->gpiolock);
+ return result;
}
static int ciintf_slot_reset (struct dvb_ca_en50221 *ca, int slot)
@@ -219,10 +236,12 @@ static int ciintf_poll_slot_status (struct dvb_ca_en50221 *ca, int slot)
if (slot != 0)
return -EINVAL;
+ spin_lock(&budget_av->gpiolock);
saa7146_setgpio (saa, 3, SAA7146_GPIO_INPUT);
udelay(1);
cam = saa7146_read (saa, PSR) & MASK_06;
saa7146_setgpio (saa, 3, SAA7146_GPIO_OUTLO);
+ spin_unlock(&budget_av->gpiolock);
if (cam && (!budget_av->slot_status)) {
budget_av->slot_status = 1;
@@ -242,6 +261,7 @@ static int ciintf_init (struct budget_av *budget_av)
int result;
memset (&budget_av->ca, 0, sizeof (struct dvb_ca_en50221));
+ spin_lock_init(&budget_av->gpiolock);
/* setup GPIOs */
saa7146_setgpio (saa, 1, SAA7146_GPIO_OUTHI);