return NOTIFY_DONE;
 }
 
+static void mlx4_ib_alloc_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev)
+{
+       char name[32];
+       int eq_per_port = 0;
+       int added_eqs = 0;
+       int total_eqs = 0;
+       int i, j, eq;
+
+       /* Init eq table */
+       ibdev->eq_table = NULL;
+       ibdev->eq_added = 0;
+
+       /* Legacy mode? */
+       if (dev->caps.comp_pool == 0)
+               return;
+
+       eq_per_port = rounddown_pow_of_two(dev->caps.comp_pool/
+                                       dev->caps.num_ports);
+
+       /* Init eq table */
+       added_eqs = 0;
+       mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB)
+               added_eqs += eq_per_port;
+
+       total_eqs = dev->caps.num_comp_vectors + added_eqs;
+
+       ibdev->eq_table = kzalloc(total_eqs * sizeof(int), GFP_KERNEL);
+       if (!ibdev->eq_table)
+               return;
+
+       ibdev->eq_added = added_eqs;
+
+       eq = 0;
+       mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB) {
+               for (j = 0; j < eq_per_port; j++) {
+                       sprintf(name, "mlx4-ib-%d-%d@%s",
+                               i, j, dev->pdev->bus->name);
+                       /* Set IRQ for specific name (per ring) */
+                       if (mlx4_assign_eq(dev, name, &ibdev->eq_table[eq])) {
+                               /* Use legacy (same as mlx4_en driver) */
+                               pr_warn("Can't allocate EQ %d; reverting to legacy\n", eq);
+                               ibdev->eq_table[eq] =
+                                       (eq % dev->caps.num_comp_vectors);
+                       }
+                       eq++;
+               }
+       }
+
+       /* Fill the reset of the vector with legacy EQ */
+       for (i = 0, eq = added_eqs; i < dev->caps.num_comp_vectors; i++)
+               ibdev->eq_table[eq++] = i;
+
+       /* Advertise the new number of EQs to clients */
+       ibdev->ib_dev.num_comp_vectors = total_eqs;
+}
+
+static void mlx4_ib_free_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev)
+{
+       int i;
+       int total_eqs;
+
+       /* Reset the advertised EQ number */
+       ibdev->ib_dev.num_comp_vectors = dev->caps.num_comp_vectors;
+
+       /* Free only the added eqs */
+       for (i = 0; i < ibdev->eq_added; i++) {
+               /* Don't free legacy eqs if used */
+               if (ibdev->eq_table[i] <= dev->caps.num_comp_vectors)
+                       continue;
+               mlx4_release_eq(dev, ibdev->eq_table[i]);
+       }
+
+       total_eqs = dev->caps.num_comp_vectors + ibdev->eq_added;
+       memset(ibdev->eq_table, 0, total_eqs * sizeof(int));
+       kfree(ibdev->eq_table);
+
+       ibdev->eq_table = NULL;
+       ibdev->eq_added = 0;
+}
+
 static void *mlx4_ib_add(struct mlx4_dev *dev)
 {
        struct mlx4_ib_dev *ibdev;
                        (1ull << IB_USER_VERBS_CMD_CLOSE_XRCD);
        }
 
+       mlx4_ib_alloc_eqs(dev, ibdev);
+
        spin_lock_init(&iboe->lock);
 
        if (init_node_data(ibdev))
        mlx4_foreach_port(p, dev, MLX4_PORT_TYPE_IB)
                mlx4_CLOSE_PORT(dev, p);
 
+       mlx4_ib_free_eqs(dev, ibdev);
+
        mlx4_uar_free(dev, &ibdev->priv_uar);
        mlx4_pd_free(dev, ibdev->priv_pdn);
        ib_dealloc_device(&ibdev->ib_dev);