summaryrefslogtreecommitdiffstats
path: root/drivers/net/davinci_emac.c
diff options
context:
space:
mode:
authorHeinrich Toews <heinrich.toews@wago.com>2016-09-28 14:09:38 +0000
committerSascha Hauer <s.hauer@pengutronix.de>2018-12-13 10:25:32 +0100
commit244f7dc385271c3fad5f3b842416985540b3664f (patch)
tree610e497b1c6381b59f7945ba57fb6aea4d76ba71 /drivers/net/davinci_emac.c
parent804770590556be5c922c9fb7e779e72805911e57 (diff)
downloadbarebox-244f7dc385271c3fad5f3b842416985540b3664f.tar.gz
barebox-244f7dc385271c3fad5f3b842416985540b3664f.tar.xz
net: davinci-emac: fix buggy channel tear down
Druing a barebox_shutdown() already probed platform devices are being halted. While trying to halt the davinci emac a channel tear down operation is triggered which leads due to a missing DMA pointer configuration to a memory corruption whithin the decompressed kernel memory. In this case the devices failed to boot and are completely freezed. In the davinci driver DMA initialisation is only done during the opening of the device which is done only when the device is setup for communication. The problem was solved by adding DMA init code to emacs_init() which is called shortly after the probing of the device. In this case the tearing down of the channels completes successfully. Signed-off-by: Oleg Karfich <oleg.karfich@wago.com>
Diffstat (limited to 'drivers/net/davinci_emac.c')
-rw-r--r--drivers/net/davinci_emac.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index 2fccd4681e..2f6091d155 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -173,6 +173,17 @@ static int davinci_emac_set_ethaddr(struct eth_device *edev, const unsigned char
static int davinci_emac_init(struct eth_device *edev)
{
+ struct davinci_emac_priv *priv = edev->priv;
+ uint32_t cnt;
+
+ /* Set DMA head and completion pointers to 0 */
+ for(cnt = 0; cnt < 8; cnt++) {
+ writel(0, (void *)priv->adap_emac + EMAC_TX0HDP + 4 * cnt);
+ writel(0, (void *)priv->adap_emac + EMAC_RX0HDP + 4 * cnt);
+ writel(0, (void *)priv->adap_emac + EMAC_TX0CP + 4 * cnt);
+ writel(0, (void *)priv->adap_emac + EMAC_RX0CP + 4 * cnt);
+ }
+
dev_dbg(&edev->dev, "* emac_init\n");
return 0;
}