struct cpsw_ale                 *ale;
        bool                            rx_pause;
        bool                            tx_pause;
+       bool                            quirk_irq;
+       bool                            rx_irq_disabled;
+       bool                            tx_irq_disabled;
        /* snapshot of IRQ numbers */
        u32 irqs_table[4];
        u32 num_irqs;
        writel(0, &priv->wr_regs->tx_en);
        cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
 
+       if (priv->quirk_irq) {
+               disable_irq_nosync(priv->irqs_table[1]);
+               priv->tx_irq_disabled = true;
+       }
+
        napi_schedule(&priv->napi_tx);
        return IRQ_HANDLED;
 }
        cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
        writel(0, &priv->wr_regs->rx_en);
 
+       if (priv->quirk_irq) {
+               disable_irq_nosync(priv->irqs_table[0]);
+               priv->rx_irq_disabled = true;
+       }
+
        napi_schedule(&priv->napi_rx);
        return IRQ_HANDLED;
 }
        if (num_tx < budget) {
                napi_complete(napi_tx);
                writel(0xff, &priv->wr_regs->tx_en);
+               if (priv->quirk_irq && priv->tx_irq_disabled) {
+                       priv->tx_irq_disabled = false;
+                       enable_irq(priv->irqs_table[1]);
+               }
        }
 
        if (num_tx)
        if (num_rx < budget) {
                napi_complete(napi_rx);
                writel(0xff, &priv->wr_regs->rx_en);
+               if (priv->quirk_irq && priv->rx_irq_disabled) {
+                       priv->rx_irq_disabled = false;
+                       enable_irq(priv->irqs_table[0]);
+               }
        }
 
        if (num_rx)
                napi_enable(&priv_sl0->napi_rx);
                napi_enable(&priv_sl0->napi_tx);
 
+               if (priv_sl0->tx_irq_disabled) {
+                       priv_sl0->tx_irq_disabled = false;
+                       enable_irq(priv->irqs_table[1]);
+               }
+
+               if (priv_sl0->rx_irq_disabled) {
+                       priv_sl0->rx_irq_disabled = false;
+                       enable_irq(priv->irqs_table[0]);
+               }
+
                if (WARN_ON(!priv->data.rx_descs))
                        priv->data.rx_descs = 128;
 
        return ret;
 }
 
+#define CPSW_QUIRK_IRQ         BIT(0)
+
+static struct platform_device_id cpsw_devtype[] = {
+       {
+               /* keep it for existing comaptibles */
+               .name = "cpsw",
+               .driver_data = CPSW_QUIRK_IRQ,
+       }, {
+               .name = "am335x-cpsw",
+               .driver_data = CPSW_QUIRK_IRQ,
+       }, {
+               .name = "am4372-cpsw",
+               .driver_data = 0,
+       }, {
+               .name = "dra7-cpsw",
+               .driver_data = 0,
+       }, {
+               /* sentinel */
+       }
+};
+MODULE_DEVICE_TABLE(platform, cpsw_devtype);
+
+enum ti_cpsw_type {
+       CPSW = 0,
+       AM335X_CPSW,
+       AM4372_CPSW,
+       DRA7_CPSW,
+};
+
+static const struct of_device_id cpsw_of_mtable[] = {
+       { .compatible = "ti,cpsw", .data = &cpsw_devtype[CPSW], },
+       { .compatible = "ti,am335x-cpsw", .data = &cpsw_devtype[AM335X_CPSW], },
+       { .compatible = "ti,am4372-cpsw", .data = &cpsw_devtype[AM4372_CPSW], },
+       { .compatible = "ti,dra7-cpsw", .data = &cpsw_devtype[DRA7_CPSW], },
+       { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, cpsw_of_mtable);
+
 static int cpsw_probe(struct platform_device *pdev)
 {
        struct cpsw_platform_data       *data;
        struct cpsw_ale_params          ale_params;
        void __iomem                    *ss_regs;
        struct resource                 *res, *ss_res;
+       const struct of_device_id       *of_id;
        u32 slave_offset, sliver_offset, slave_size;
        int ret = 0, i;
        int irq;
                goto clean_ale_ret;
        }
 
+       of_id = of_match_device(cpsw_of_mtable, &pdev->dev);
+       if (of_id) {
+               pdev->id_entry = of_id->data;
+               if (pdev->id_entry->driver_data)
+                       priv->quirk_irq = true;
+       }
+
        /* Grab RX and TX IRQs. Note that we also have RX_THRESHOLD and
         * MISC IRQs which are always kept disabled with this driver so
         * we will not request them.
 
 static SIMPLE_DEV_PM_OPS(cpsw_pm_ops, cpsw_suspend, cpsw_resume);
 
-static const struct of_device_id cpsw_of_mtable[] = {
-       { .compatible = "ti,cpsw", },
-       { /* sentinel */ },
-};
-MODULE_DEVICE_TABLE(of, cpsw_of_mtable);
-
 static struct platform_driver cpsw_driver = {
        .driver = {
                .name    = "cpsw",