mirror of
https://github.com/torvalds/linux.git
synced 2024-11-17 09:31:50 +00:00
Merge branch 'cpsw-errata-workaround'
Mugunthan V N says:
====================
Add AM335x PG1.0 CPSW errata workaround
With commit 870915feab
("drivers: net: cpsw: remove
disable_irq/enable_irq as irq can be masked from cpsw itself"),
CPSW on AM335x beagle bone white is broken as there is a errata
for AM335x PG1.0. This patch series implements the workaround by
disabling the interrupts from ARM IRQ controller for AM335x SoC
in addition to the masking of interrupts in CPSW.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
646244b223
@ -700,7 +700,7 @@
|
||||
};
|
||||
|
||||
mac: ethernet@4a100000 {
|
||||
compatible = "ti,cpsw";
|
||||
compatible = "ti,am335x-cpsw","ti,cpsw";
|
||||
ti,hwmods = "cpgmac0";
|
||||
clocks = <&cpsw_125mhz_gclk>, <&cpsw_cpts_rft_clk>;
|
||||
clock-names = "fck", "cpts";
|
||||
|
@ -1399,7 +1399,7 @@
|
||||
};
|
||||
|
||||
mac: ethernet@4a100000 {
|
||||
compatible = "ti,cpsw";
|
||||
compatible = "ti,dra7-cpsw","ti,cpsw";
|
||||
ti,hwmods = "gmac";
|
||||
clocks = <&dpll_gmac_ck>, <&gmac_gmii_ref_clk_div>;
|
||||
clock-names = "fck", "cpts";
|
||||
|
@ -387,6 +387,9 @@ struct cpsw_priv {
|
||||
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;
|
||||
@ -755,6 +758,11 @@ static irqreturn_t cpsw_tx_interrupt(int irq, void *dev_id)
|
||||
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;
|
||||
}
|
||||
@ -766,6 +774,11 @@ static irqreturn_t cpsw_rx_interrupt(int irq, void *dev_id)
|
||||
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;
|
||||
}
|
||||
@ -779,6 +792,10 @@ static int cpsw_tx_poll(struct napi_struct *napi_tx, int budget)
|
||||
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)
|
||||
@ -796,6 +813,10 @@ static int cpsw_rx_poll(struct napi_struct *napi_rx, int budget)
|
||||
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)
|
||||
@ -1267,6 +1288,16 @@ static int cpsw_ndo_open(struct net_device *ndev)
|
||||
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;
|
||||
|
||||
@ -2128,6 +2159,44 @@ static int cpsw_probe_dual_emac(struct platform_device *pdev,
|
||||
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;
|
||||
@ -2137,6 +2206,7 @@ static int cpsw_probe(struct platform_device *pdev)
|
||||
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;
|
||||
@ -2327,6 +2397,13 @@ static int cpsw_probe(struct platform_device *pdev)
|
||||
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.
|
||||
@ -2491,12 +2568,6 @@ static int cpsw_resume(struct device *dev)
|
||||
|
||||
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",
|
||||
|
Loading…
Reference in New Issue
Block a user