RE: [PATCH 01/13] staging: comedi: pcmuio: fix interrupt requests

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thursday, July 25, 2013 5:34 AM, Ian Abbott wrote:
> On 2013-07-24 19:45, H Hartley Sweeten wrote:
>> Legacy (ISA) interrupts are not sharable so this driver should not
>> be passing the IRQF_SHARED flag when requesting the interrupts.
>>
>> This driver supports two board types:
>>    PCM-UIO48 with one asic (one interrupt source)
>>    PCM-UIO96 with two asics (two interrupt sources)
>>
>> The PCM-UIO96 has a jumper that allows the two interrupt sources to
>> share an interrupt. This is safe for legacy interrupts as long as
>> the "shared" interrupt is handled by a single driver.
>>
>> Modify the request_irq() code in this driver to correctly request the
>> interrupts. For the PCM-UI048 case (one asic) only one request_irq()
>> is needed. For the PCM-UIO96 (two asics) there are two cases:
>>
>>    1) interrupt is shared, one request_irq() call
>>    2) two interrupts, two request_irq() calls
>>
>> Do the first request_irq() in all cases. Only do the second if the
>> boardinfo indicates that the board has two asics and the user passed
>> the 2nd interrupt number.
>>
>> Pack the two interrupt numbers in dev->irq instead of storing them in
>> the private data. During the detach of the board, this driver will
>> free the 2nd irq if needed and the core will free the 1st.
>>
>> Move the board reset and interrupt request code so it occurs early
>> in the attach. We can then check dev->irq to see if the subdevice
>> interrupt support actually needs to be initialized.
>>
>> Add a call to pcmuio_reset() in the (*detach) to make sure the
>> interrupts are disabled before freeing the irqs.
>>
>> Signed-off-by: H Hartley Sweeten <hsweeten@xxxxxxxxxxxxxxxxxxx>
>> Cc: Ian Abbott <abbotti@xxxxxxxxx>
>> Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
>> ---
>>   drivers/staging/comedi/drivers/pcmuio.c | 96 ++++++++++++++++++---------------
>>   1 file changed, 54 insertions(+), 42 deletions(-)
>
> Packing the two irq values in a single member seems a bit hackish.  I 
> think adding an 'irq2' member to struct pcmuio_private would be cleaner.

It is a bit "hackish" but the hack is documented with comments. The 'irq' member
is only used by the core in comedi_legacy_detach() so the hack will not have any
side effects.

<snip>

>> @@ -617,6 +607,39 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
>>   	for (asic = 0; asic < PCMUIO_MAX_ASICS; ++asic)
>>   		spin_lock_init(&devpriv->asics[asic].spinlock);
>>
>> +	pcmuio_reset(dev);
>> +
>> +	/* request the 1st irq */
>> +	irq = it->options[1];
>> +	if (irq) {
>> +		ret = request_irq(irq, pcmuio_interrupt, 0,
>> +				  board->name, dev);
>> +		if (ret == 0) {
>> +			/* save the irq for the core to free */
>> +			dev->irq = irq;
>> +		}
>> +	}
>> +
>> +	/* request the 2nd irq if needed */
>> +	if (board->num_asics == 2 && dev->irq) {
>> +		irq = it->options[2];
>> +		if (irq && irq != dev->irq) {
>> +			/* 1st and 2nd irq differ */
>> +			ret = request_irq(irq, pcmuio_interrupt, 0,
>> +					  board->name, dev);
>> +			if (ret == 0) {
>> +				/* save the irq for (*detach) to free */
>> +				dev->irq |= (irq << 8);
>> +			} else {
>> +				free_irq(dev->irq, dev);
>> +				dev->irq = 0;
>> +			}
>> +		} else {
>> +			/* 1st and 2nd irq are the same (or 2nd is zero) */
>> +			dev->irq |= (irq << 8);
>> +		}
>> +	}
>> +
>
> It could possibly allow just the second IRQ to be used even if the first 
> IRQ is not used (0), but the original driver didn't allow that.

This might be desired?

>>   	n_subdevs = board->num_asics * 2;
>>   	devpriv->sprivs = kcalloc(n_subdevs, sizeof(*subpriv), GFP_KERNEL);
>>   	if (!devpriv->sprivs)
>> @@ -639,7 +662,7 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
>>   		s->n_chan = 24;
>>
>>   		/* subdevices 0 and 2 suppport interrupts */
>> -		if ((sdev_no % 2) == 0) {
>> +		if ((sdev_no % 2) == 0 && dev->irq) {
>
> You've checked if irq is set before allowing commands to be set-up, but 
> you haven't checked which of the possibly two irqs is set.

Hmm.. True.

I guess this test should really be:

		if ((sdev_no % 2) == 0 && (dev->irq >> (8 * (sdev_no % 2)))) {

Then the subdevice command operations will only be hooked up if the irq is
available.

Can this be fixed as a separate patch or would you prefer that I rebase the
series?

Also, if you would prefer using a separate 'irq' member in the private data for
the 2nd irq let me know. This will of course effect multiple parts of the series.

Thanks,
Hartley

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel




[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux