diff options
author | Heinrich Toews <heinrich.toews@wago.com> | 2016-09-28 14:09:38 +0000 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2018-12-13 10:25:32 +0100 |
commit | 244f7dc385271c3fad5f3b842416985540b3664f (patch) | |
tree | 610e497b1c6381b59f7945ba57fb6aea4d76ba71 /drivers/net | |
parent | 804770590556be5c922c9fb7e779e72805911e57 (diff) | |
download | barebox-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')
-rw-r--r-- | drivers/net/davinci_emac.c | 11 |
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; } |