diff options
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/comedi/drivers/amplc_pci230.c | 99 |
1 files changed, 32 insertions, 67 deletions
diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 7a8291adecea..727de3d75c7b 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -421,16 +421,15 @@ * (Potentially) shared resources and their owners */ enum { - RES_Z2CT0, /* Z2-CT0 */ - RES_Z2CT1, /* Z2-CT1 */ - RES_Z2CT2, /* Z2-CT2 */ - NUM_RESOURCES /* Number of (potentially) shared resources. */ + RES_Z2CT0 = (1U << 0), /* Z2-CT0 */ + RES_Z2CT1 = (1U << 1), /* Z2-CT1 */ + RES_Z2CT2 = (1U << 2) /* Z2-CT2 */ }; enum { - OWNER_NONE, /* Not owned */ OWNER_AICMD, /* Owned by AI command */ - OWNER_AOCMD /* Owned by AO command */ + OWNER_AOCMD, /* Owned by AO command */ + NUM_OWNERS /* Number of owners */ }; /* @@ -502,7 +501,7 @@ struct pci230_private { unsigned short adcg; /* ADCG register value */ unsigned char int_en; /* Interrupt enable bits */ unsigned char ier; /* Copy of interrupt enable register */ - unsigned char res_owner[NUM_RESOURCES]; /* Shared resource owners */ + unsigned char res_owned[NUM_OWNERS]; /* Owned resources */ bool intr_running:1; /* Flag set in interrupt routine */ bool ai_bipolar:1; /* Flag AI range is bipolar */ bool ao_bipolar:1; /* Flag AO range is bipolar */ @@ -604,77 +603,43 @@ static void pci230_ao_write_fifo(struct comedi_device *dev, devpriv->daqio + PCI230P2_DACDATA); } -static int pci230_get_resources(struct comedi_device *dev, - unsigned int res_mask, unsigned char owner) +static bool pci230_claim_shared(struct comedi_device *dev, + unsigned char res_mask, unsigned int owner) { struct pci230_private *devpriv = dev->private; - int ok; - unsigned int i; - unsigned int b; - unsigned int claimed; + unsigned int o; unsigned long irqflags; - ok = 1; - claimed = 0; spin_lock_irqsave(&devpriv->res_spinlock, irqflags); - for (b = 1, i = 0; i < NUM_RESOURCES && res_mask; b <<= 1, i++) { - if (res_mask & b) { - res_mask &= ~b; - if (devpriv->res_owner[i] == OWNER_NONE) { - devpriv->res_owner[i] = owner; - claimed |= b; - } else if (devpriv->res_owner[i] != owner) { - for (b = 1, i = 0; claimed; b <<= 1, i++) { - if (claimed & b) { - devpriv->res_owner[i] = - OWNER_NONE; - claimed &= ~b; - } - } - ok = 0; - break; - } + for (o = 0; o < NUM_OWNERS; o++) { + if (o == owner) + continue; + if (devpriv->res_owned[o] & res_mask) { + spin_unlock_irqrestore(&devpriv->res_spinlock, + irqflags); + return false; } } + devpriv->res_owned[owner] |= res_mask; spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags); - return ok; -} - -static int pci230_get_one_resource(struct comedi_device *dev, - unsigned int resource, unsigned char owner) -{ - return pci230_get_resources(dev, 1U << resource, owner); + return true; } -static void pci230_put_resources(struct comedi_device *dev, - unsigned int res_mask, unsigned char owner) +static void pci230_release_shared(struct comedi_device *dev, + unsigned char res_mask, unsigned int owner) { struct pci230_private *devpriv = dev->private; - unsigned int i; - unsigned int b; unsigned long irqflags; spin_lock_irqsave(&devpriv->res_spinlock, irqflags); - for (b = 1, i = 0; i < NUM_RESOURCES && res_mask; b <<= 1, i++) { - if (res_mask & b) { - res_mask &= ~b; - if (devpriv->res_owner[i] == owner) - devpriv->res_owner[i] = OWNER_NONE; - } - } + devpriv->res_owned[owner] &= ~res_mask; spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags); } -static void pci230_put_one_resource(struct comedi_device *dev, - unsigned int resource, unsigned char owner) -{ - pci230_put_resources(dev, 1U << resource, owner); -} - -static void pci230_put_all_resources(struct comedi_device *dev, - unsigned char owner) +static void pci230_release_all_resources(struct comedi_device *dev, + unsigned int owner) { - pci230_put_resources(dev, (1U << NUM_RESOURCES) - 1, owner); + pci230_release_shared(dev, (unsigned char)~0, owner); } static unsigned int pci230_divide_ns(uint64_t ns, unsigned int timebase, @@ -1105,7 +1070,7 @@ static void pci230_ao_stop(struct comedi_device *dev, devpriv->daqio + PCI230_DACCON); } /* Release resources. */ - pci230_put_all_resources(dev, OWNER_AOCMD); + pci230_release_all_resources(dev, OWNER_AOCMD); } static void pci230_handle_ao_nofifo(struct comedi_device *dev, @@ -1401,7 +1366,7 @@ static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (cmd->scan_begin_src == TRIG_TIMER) { /* Claim Z2-CT1. */ - if (!pci230_get_one_resource(dev, RES_Z2CT1, OWNER_AOCMD)) + if (!pci230_claim_shared(dev, RES_Z2CT1, OWNER_AOCMD)) return -EBUSY; } @@ -1957,7 +1922,7 @@ static void pci230_ai_stop(struct comedi_device *dev, outw(devpriv->adccon | PCI230_ADC_FIFO_RESET, devpriv->daqio + PCI230_ADCCON); /* Release resources. */ - pci230_put_all_resources(dev, OWNER_AICMD); + pci230_release_all_resources(dev, OWNER_AICMD); } static void pci230_ai_start(struct comedi_device *dev, @@ -2106,7 +2071,7 @@ static void pci230_ai_start(struct comedi_device *dev, } } else if (cmd->convert_src != TRIG_INT) { /* No longer need Z2-CT2. */ - pci230_put_one_resource(dev, RES_Z2CT2, OWNER_AICMD); + pci230_release_shared(dev, RES_Z2CT2, OWNER_AICMD); } } } @@ -2237,17 +2202,17 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) * Need Z2-CT2 to supply a conversion trigger source at a high * logic level, even if not doing timed conversions. */ - res_mask |= 1U << RES_Z2CT2; + res_mask |= RES_Z2CT2; if (cmd->scan_begin_src != TRIG_FOLLOW) { /* Using Z2-CT0 monostable to gate Z2-CT2 conversion timer */ - res_mask |= 1U << RES_Z2CT0; + res_mask |= RES_Z2CT0; if (cmd->scan_begin_src == TRIG_TIMER) { /* Using Z2-CT1 for scan frequency */ - res_mask |= 1U << RES_Z2CT1; + res_mask |= RES_Z2CT1; } } /* Claim resources. */ - if (!pci230_get_resources(dev, res_mask, OWNER_AICMD)) + if (!pci230_claim_shared(dev, res_mask, OWNER_AICMD)) return -EBUSY; /* Get number of scans required. */ |