On Mon, Sep 24, 2018 at 02:38:15PM +0200, Christian König wrote: > Add a callback to amdgpu_ih_process to remove most of the IV logic. > > Signed-off-by: Christian König <christian.koenig@xxxxxxx> Acked-by: Huang Rui <ray.huang@xxxxxxx> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 24 +++++------------------- > drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 4 +++- > drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 31 ++++++++++++++++++++++++++++++- > 3 files changed, 38 insertions(+), 21 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > index 15fb0f9738ab..8af67f649660 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > @@ -24,7 +24,6 @@ > #include <drm/drmP.h> > #include "amdgpu.h" > #include "amdgpu_ih.h" > -#include "amdgpu_amdkfd.h" > > /** > * amdgpu_ih_ring_init - initialize the IH state > @@ -129,9 +128,10 @@ void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih) > * Interrupt hander (VI), walk the IH ring. > * Returns irq process return code. > */ > -int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih) > +int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, > + void (*callback)(struct amdgpu_device *adev, > + struct amdgpu_ih_ring *ih)) > { > - struct amdgpu_iv_entry entry; > u32 wptr; > > if (!ih->enabled || adev->shutdown) > @@ -150,24 +150,10 @@ int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih) > rmb(); > > while (ih->rptr != wptr) { > - u32 ring_index = ih->rptr >> 2; > - > - /* Prescreening of high-frequency interrupts */ > - if (!amdgpu_ih_prescreen_iv(adev)) { > - ih->rptr &= ih->ptr_mask; > - continue; > - } > - > - /* Before dispatching irq to IP blocks, send it to amdkfd */ > - amdgpu_amdkfd_interrupt(adev, > - (const void *) &ih->ring[ring_index]); > - > - entry.iv_entry = (const uint32_t *)&ih->ring[ring_index]; > - amdgpu_ih_decode_iv(adev, &entry); > + callback(adev, ih); > ih->rptr &= ih->ptr_mask; > - > - amdgpu_irq_dispatch(adev, &entry); > } > + > amdgpu_ih_set_rptr(adev); > atomic_set(&ih->lock, 0); > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > index 3e55f985005c..fd2bbaa20ab4 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > @@ -85,6 +85,8 @@ struct amdgpu_ih_funcs { > int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, > unsigned ring_size, bool use_bus_addr); > void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); > -int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); > +int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, > + void (*callback)(struct amdgpu_device *adev, > + struct amdgpu_ih_ring *ih)); > > #endif > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c > index aaa8545e458a..2fca08e130b6 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c > @@ -51,6 +51,7 @@ > #include "atom.h" > #include "amdgpu_connectors.h" > #include "amdgpu_trace.h" > +#include "amdgpu_amdkfd.h" > > #include <linux/pm_runtime.h> > > @@ -146,6 +147,34 @@ void amdgpu_irq_disable_all(struct amdgpu_device *adev) > spin_unlock_irqrestore(&adev->irq.lock, irqflags); > } > > +/** > + * amdgpu_irq_callback - callback from the IH ring > + * > + * @adev: amdgpu device pointer > + * @ih: amdgpu ih ring > + * > + * Callback from IH ring processing to handle the entry at the current position > + * and advance the read pointer. > + */ > +static void amdgpu_irq_callback(struct amdgpu_device *adev, > + struct amdgpu_ih_ring *ih) > +{ > + u32 ring_index = ih->rptr >> 2; > + struct amdgpu_iv_entry entry; > + > + /* Prescreening of high-frequency interrupts */ > + if (!amdgpu_ih_prescreen_iv(adev)) > + return; > + > + /* Before dispatching irq to IP blocks, send it to amdkfd */ > + amdgpu_amdkfd_interrupt(adev, (const void *) &ih->ring[ring_index]); > + > + entry.iv_entry = (const uint32_t *)&ih->ring[ring_index]; > + amdgpu_ih_decode_iv(adev, &entry); > + > + amdgpu_irq_dispatch(adev, &entry); > +} > + > /** > * amdgpu_irq_handler - IRQ handler > * > @@ -163,7 +192,7 @@ irqreturn_t amdgpu_irq_handler(int irq, void *arg) > struct amdgpu_device *adev = dev->dev_private; > irqreturn_t ret; > > - ret = amdgpu_ih_process(adev, &adev->irq.ih); > + ret = amdgpu_ih_process(adev, &adev->irq.ih, amdgpu_irq_callback); > if (ret == IRQ_HANDLED) > pm_runtime_mark_last_busy(dev->dev); > return ret; > -- > 2.14.1 > > _______________________________________________ > amd-gfx mailing list > amd-gfx@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/amd-gfx _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx