staging: comedi: mite: make mite_ack_linkc() handle mite_sync_dma()
The mite dma is always synced on a LINKC status. Some of the mite users sync the dma regadless of the status. Add a 'sync' parameter to mite_ack_linkc() to force a dma sync. Then do the dma sync as needed. Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> Reviewed-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
3da088cae2
commit
f7d005c33c
|
@ -779,15 +779,21 @@ static unsigned int mite_get_status(struct mite_channel *mite_chan)
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int mite_ack_linkc(struct mite_channel *mite_chan,
|
unsigned int mite_ack_linkc(struct mite_channel *mite_chan,
|
||||||
struct comedi_subdevice *s)
|
struct comedi_subdevice *s,
|
||||||
|
bool sync)
|
||||||
{
|
{
|
||||||
struct mite_struct *mite = mite_chan->mite;
|
struct mite_struct *mite = mite_chan->mite;
|
||||||
unsigned int status;
|
unsigned int status;
|
||||||
|
|
||||||
status = mite_get_status(mite_chan);
|
status = mite_get_status(mite_chan);
|
||||||
if (status & CHSR_LINKC)
|
if (status & CHSR_LINKC) {
|
||||||
writel(CHOR_CLRLC,
|
writel(CHOR_CLRLC,
|
||||||
mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
|
mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
|
||||||
|
sync = true;
|
||||||
|
}
|
||||||
|
if (sync)
|
||||||
|
mite_sync_dma(mite_chan, s);
|
||||||
|
|
||||||
if (status & CHSR_XFERR) {
|
if (status & CHSR_XFERR) {
|
||||||
dev_err(s->device->class_dev,
|
dev_err(s->device->class_dev,
|
||||||
"mite: transfer error %08x\n", status);
|
"mite: transfer error %08x\n", status);
|
||||||
|
|
|
@ -93,8 +93,8 @@ void mite_dma_arm(struct mite_channel *mite_chan);
|
||||||
void mite_dma_disarm(struct mite_channel *mite_chan);
|
void mite_dma_disarm(struct mite_channel *mite_chan);
|
||||||
void mite_sync_dma(struct mite_channel *mite_chan, struct comedi_subdevice *s);
|
void mite_sync_dma(struct mite_channel *mite_chan, struct comedi_subdevice *s);
|
||||||
u32 mite_bytes_in_transit(struct mite_channel *mite_chan);
|
u32 mite_bytes_in_transit(struct mite_channel *mite_chan);
|
||||||
unsigned int mite_ack_linkc(struct mite_channel *mite_chan,
|
unsigned int mite_ack_linkc(struct mite_channel *, struct comedi_subdevice *,
|
||||||
struct comedi_subdevice *s);
|
bool sync);
|
||||||
int mite_done(struct mite_channel *mite_chan);
|
int mite_done(struct mite_channel *mite_chan);
|
||||||
|
|
||||||
void mite_prep_dma(struct mite_channel *mite_chan,
|
void mite_prep_dma(struct mite_channel *mite_chan,
|
||||||
|
|
|
@ -3632,10 +3632,8 @@ static void handle_cdio_interrupt(struct comedi_device *dev)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
|
spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
|
||||||
if (devpriv->cdo_mite_chan) {
|
if (devpriv->cdo_mite_chan)
|
||||||
mite_ack_linkc(devpriv->cdo_mite_chan, s);
|
mite_ack_linkc(devpriv->cdo_mite_chan, s, true);
|
||||||
mite_sync_dma(devpriv->cdo_mite_chan, s);
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
|
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
|
||||||
|
|
||||||
cdio_status = ni_readl(dev, NI_M_CDIO_STATUS_REG);
|
cdio_status = ni_readl(dev, NI_M_CDIO_STATUS_REG);
|
||||||
|
@ -5150,21 +5148,12 @@ static irqreturn_t ni_E_interrupt(int irq, void *d)
|
||||||
#ifdef PCIDMA
|
#ifdef PCIDMA
|
||||||
if (devpriv->mite) {
|
if (devpriv->mite) {
|
||||||
unsigned long flags_too;
|
unsigned long flags_too;
|
||||||
unsigned int m_status;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&devpriv->mite_channel_lock, flags_too);
|
spin_lock_irqsave(&devpriv->mite_channel_lock, flags_too);
|
||||||
if (s_ai && devpriv->ai_mite_chan) {
|
if (s_ai && devpriv->ai_mite_chan)
|
||||||
m_status = mite_ack_linkc(devpriv->ai_mite_chan, s_ai);
|
mite_ack_linkc(devpriv->ai_mite_chan, s_ai, false);
|
||||||
if (m_status & CHSR_LINKC)
|
if (s_ao && devpriv->ao_mite_chan)
|
||||||
mite_sync_dma(devpriv->ai_mite_chan, s_ai);
|
mite_ack_linkc(devpriv->ao_mite_chan, s_ao, false);
|
||||||
}
|
|
||||||
|
|
||||||
if (s_ao && devpriv->ao_mite_chan) {
|
|
||||||
m_status = mite_ack_linkc(devpriv->ao_mite_chan, s_ao);
|
|
||||||
if (m_status & CHSR_LINKC)
|
|
||||||
mite_sync_dma(devpriv->ao_mite_chan, s_ao);
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags_too);
|
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags_too);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -400,13 +400,8 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
|
||||||
|
|
||||||
spin_lock(&devpriv->mite_channel_lock);
|
spin_lock(&devpriv->mite_channel_lock);
|
||||||
if (devpriv->di_mite_chan) {
|
if (devpriv->di_mite_chan) {
|
||||||
unsigned int m_status = mite_ack_linkc(devpriv->di_mite_chan,
|
mite_ack_linkc(devpriv->di_mite_chan, s, false);
|
||||||
s);
|
/* XXX need to byteswap sync'ed dma */
|
||||||
|
|
||||||
if (m_status & CHSR_LINKC) {
|
|
||||||
mite_sync_dma(devpriv->di_mite_chan, s);
|
|
||||||
/* XXX need to byteswap */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
spin_unlock(&devpriv->mite_channel_lock);
|
spin_unlock(&devpriv->mite_channel_lock);
|
||||||
|
|
||||||
|
|
|
@ -428,10 +428,8 @@ void ni_tio_handle_interrupt(struct ni_gpct *counter,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
spin_lock_irqsave(&counter->lock, flags);
|
spin_lock_irqsave(&counter->lock, flags);
|
||||||
if (counter->mite_chan) {
|
if (counter->mite_chan)
|
||||||
mite_ack_linkc(counter->mite_chan, s);
|
mite_ack_linkc(counter->mite_chan, s, true);
|
||||||
mite_sync_dma(counter->mite_chan, s);
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&counter->lock, flags);
|
spin_unlock_irqrestore(&counter->lock, flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(ni_tio_handle_interrupt);
|
EXPORT_SYMBOL_GPL(ni_tio_handle_interrupt);
|
||||||
|
|
Loading…
Reference in New Issue