MPI2_RPHI_MSIX_INDEX_SHIFT),
                                                &ioc->chip->ReplyPostHostIndex);
                        }
-                       completed_cmds = 1;
+                       if (!reply_q->irq_poll_scheduled) {
+                               reply_q->irq_poll_scheduled = true;
+                               irq_poll_sched(&reply_q->irqpoll);
+                       }
+                               atomic_dec(&reply_q->busy);
+                               return completed_cmds;
                }
                if (request_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED)
                        goto out;
 
        if (ioc->mask_interrupts)
                return IRQ_NONE;
-
+       if (reply_q->irq_poll_scheduled)
+               return IRQ_HANDLED;
        return ((_base_process_reply_queue(reply_q) > 0) ?
                        IRQ_HANDLED : IRQ_NONE);
 }
 
+/**
+ * _base_irqpoll - IRQ poll callback handler
+ * @irqpoll - irq_poll object
+ * @budget - irq poll weight
+ *
+ * returns number of reply descriptors processed
+ */
+static int
+_base_irqpoll(struct irq_poll *irqpoll, int budget)
+{
+       struct adapter_reply_queue *reply_q;
+       int num_entries = 0;
+
+       reply_q = container_of(irqpoll, struct adapter_reply_queue,
+                       irqpoll);
+       if (reply_q->irq_line_enable) {
+               disable_irq(reply_q->os_irq);
+               reply_q->irq_line_enable = false;
+       }
+       num_entries = _base_process_reply_queue(reply_q);
+       if (num_entries < budget) {
+               irq_poll_complete(irqpoll);
+               reply_q->irq_poll_scheduled = false;
+               reply_q->irq_line_enable = true;
+               enable_irq(reply_q->os_irq);
+       }
+
+       return num_entries;
+}
+
+/**
+ * _base_init_irqpolls - initliaze IRQ polls
+ * @ioc: per adapter object
+ *
+ * returns nothing
+ */
+static void
+_base_init_irqpolls(struct MPT3SAS_ADAPTER *ioc)
+{
+       struct adapter_reply_queue *reply_q, *next;
+
+       if (list_empty(&ioc->reply_queue_list))
+               return;
+
+       list_for_each_entry_safe(reply_q, next, &ioc->reply_queue_list, list) {
+               irq_poll_init(&reply_q->irqpoll,
+                       ioc->hba_queue_depth/4, _base_irqpoll);
+               reply_q->irq_poll_scheduled = false;
+               reply_q->irq_line_enable = true;
+               reply_q->os_irq = pci_irq_vector(ioc->pdev,
+                   reply_q->msix_index);
+       }
+}
+
 /**
  * _base_is_controller_msix_enabled - is controller support muli-reply queues
  * @ioc: per adapter object
                /* TMs are on msix_index == 0 */
                if (reply_q->msix_index == 0)
                        continue;
+               if (reply_q->irq_poll_scheduled) {
+                       /* Calling irq_poll_disable will wait for any pending
+                        * callbacks to have completed.
+                        */
+                       irq_poll_disable(&reply_q->irqpoll);
+                       irq_poll_enable(&reply_q->irqpoll);
+                       reply_q->irq_poll_scheduled = false;
+                       reply_q->irq_line_enable = true;
+                       enable_irq(reply_q->os_irq);
+                       continue;
+               }
                synchronize_irq(pci_irq_vector(ioc->pdev, reply_q->msix_index));
        }
 }
        if (r)
                goto out_fail;
 
+       if (!ioc->is_driver_loading)
+               _base_init_irqpolls(ioc);
        /* Use the Combined reply queue feature only for SAS3 C0 & higher
         * revision HBAs and also only when reply queue count is greater than 8
         */
        if (r)
                goto out_free_resources;
 
+       _base_init_irqpolls(ioc);
        init_waitqueue_head(&ioc->reset_wq);
 
        /* allocate memory pd handle bitmask list */
 
 #include <scsi/scsi_eh.h>
 #include <linux/pci.h>
 #include <linux/poll.h>
+#include <linux/irq_poll.h>
 
 #include "mpt3sas_debug.h"
 #include "mpt3sas_trigger_diag.h"
  * @reply_post_free: reply post base virt address
  * @name: the name registered to request_irq()
  * @busy: isr is actively processing replies on another cpu
+ * @os_irq: irq number
+ * @irqpoll: irq_poll object
+ * @irq_poll_scheduled: Tells whether irq poll is scheduled or not
  * @list: this list
 */
 struct adapter_reply_queue {
        Mpi2ReplyDescriptorsUnion_t *reply_post_free;
        char                    name[MPT_NAME_LENGTH];
        atomic_t                busy;
+       u32                     os_irq;
+       struct irq_poll         irqpoll;
+       bool                    irq_poll_scheduled;
+       bool                    irq_line_enable;
        struct list_head        list;
 };