diff options
author | Andrew de Quincy <devnull@localhost> | 2004-11-12 15:54:49 +0000 |
---|---|---|
committer | Andrew de Quincy <devnull@localhost> | 2004-11-12 15:54:49 +0000 |
commit | 1f6bbb618acf46deff76b1a84836656b9db99b2a (patch) | |
tree | a46d61da5cab9ce90fc14167677aef76f86654b5 /linux | |
parent | 6619ffef1ac825f47ff0ac16eecfa0225bdc7f2a (diff) | |
download | mediapointer-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.c | 28 |
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); |