drm/amdgpu: send IVs to the KFD only after processing them v3
[sfrench/cifs-2.6.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_irq.c
index 6b6524f04ce09246b906a9da07a4f8d8b767a417..79b6f456f2c576c13c089fda2aa5a1350ec8f0c9 100644 (file)
@@ -149,9 +149,6 @@ static void amdgpu_irq_callback(struct amdgpu_device *adev,
        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);
 
@@ -371,39 +368,38 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev,
        unsigned client_id = entry->client_id;
        unsigned src_id = entry->src_id;
        struct amdgpu_irq_src *src;
+       bool handled = false;
        int r;
 
        trace_amdgpu_iv(entry);
 
        if (client_id >= AMDGPU_IRQ_CLIENTID_MAX) {
                DRM_DEBUG("Invalid client_id in IV: %d\n", client_id);
-               return;
-       }
 
-       if (src_id >= AMDGPU_MAX_IRQ_SRC_ID) {
+       } else  if (src_id >= AMDGPU_MAX_IRQ_SRC_ID) {
                DRM_DEBUG("Invalid src_id in IV: %d\n", src_id);
-               return;
-       }
 
-       if (adev->irq.virq[src_id]) {
+       } else if (adev->irq.virq[src_id]) {
                generic_handle_irq(irq_find_mapping(adev->irq.domain, src_id));
-       } else {
-               if (!adev->irq.client[client_id].sources) {
-                       DRM_DEBUG("Unregistered interrupt client_id: %d src_id: %d\n",
-                                 client_id, src_id);
-                       return;
-               }
 
-               src = adev->irq.client[client_id].sources[src_id];
-               if (!src) {
-                       DRM_DEBUG("Unhandled interrupt src_id: %d\n", src_id);
-                       return;
-               }
+       } else if (!adev->irq.client[client_id].sources) {
+               DRM_DEBUG("Unregistered interrupt client_id: %d src_id: %d\n",
+                         client_id, src_id);
 
+       } else if ((src = adev->irq.client[client_id].sources[src_id])) {
                r = src->funcs->process(adev, src, entry);
-               if (r)
+               if (r < 0)
                        DRM_ERROR("error processing interrupt (%d)\n", r);
+               else if (r)
+                       handled = true;
+
+       } else {
+               DRM_DEBUG("Unhandled interrupt src_id: %d\n", src_id);
        }
+
+       /* Send it to amdkfd as well if it isn't already handled */
+       if (!handled)
+               amdgpu_amdkfd_interrupt(adev, entry->iv_entry);
 }
 
 /**