diff options
author | David S. Miller <davem@davemloft.net> | 2013-10-02 21:11:50 (GMT) |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-10-02 21:11:50 (GMT) |
commit | 569943d0639c85a451ea853087cbd5f738247dd9 (patch) | |
tree | b2b7ab74e1ca5257523412a7f37a9e9967a341bb | |
parent | e18503f41f9b12132c95d7c31ca6ee5155e44e5c (diff) | |
parent | b5d82db83c1d0b327b599508a0830d25cc1f15db (diff) | |
download | linux-fsl-qoriq-569943d0639c85a451ea853087cbd5f738247dd9.tar.xz |
Merge branch 'mv643xx'
Sebastian Hesselbarth says:
====================
This patch set comprises some one-liners to fix issues with repeated
loading and unloading of a modular mv643xx_eth driver.
First two patches take care of the periodic port statistic timer, that
updates statistics by reading port registers using add_timer/mod_timer.
Patch 1 moves timer re-schedule from mib_counters_update to the timer
callback. As mib_counters_update is also called from non-timer context,
this ensures the timer is reactivated from timer context only.
Patch 2 moves initial timer schedule from _probe() time to right before
the port is actually started as the corresponding del_timer_sync is at
_stop() time. This fixes a regression, where unloading the driver from a
non-started eth device can cause the timer to access deallocated mem.
Patch 3 adds an assignment of the ports device_node to the corresponding
self-created platform_device. This is required to allow fixups based on
the device_node's compatible string later. Actually, it is also a potential
regression because we already check compatible string for Kirkwood, but
does not (yet) rely on the fixup.
All patches are based on v3.12-rc3 and have been tested on Kirkwood-based
Seagate Dockstar.
Patches 1 and 2 can also possibly queued up for -stable.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/marvell/mv643xx_eth.c | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index 7fb5677..2c210ec 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -1131,15 +1131,13 @@ static void mib_counters_update(struct mv643xx_eth_private *mp) p->rx_discard += rdlp(mp, RX_DISCARD_FRAME_CNT); p->rx_overrun += rdlp(mp, RX_OVERRUN_FRAME_CNT); spin_unlock_bh(&mp->mib_counters_lock); - - mod_timer(&mp->mib_counters_timer, jiffies + 30 * HZ); } static void mib_counters_timer_wrapper(unsigned long _mp) { struct mv643xx_eth_private *mp = (void *)_mp; - mib_counters_update(mp); + mod_timer(&mp->mib_counters_timer, jiffies + 30 * HZ); } @@ -2237,6 +2235,7 @@ static int mv643xx_eth_open(struct net_device *dev) mp->int_mask |= INT_TX_END_0 << i; } + add_timer(&mp->mib_counters_timer); port_start(mp); wrlp(mp, INT_MASK_EXT, INT_EXT_LINK_PHY | INT_EXT_TX); @@ -2534,6 +2533,7 @@ static int mv643xx_eth_shared_of_add_port(struct platform_device *pdev, if (!ppdev) return -ENOMEM; ppdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); + ppdev->dev.of_node = pnp; ret = platform_device_add_resources(ppdev, &res, 1); if (ret) @@ -2916,7 +2916,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev) mp->mib_counters_timer.data = (unsigned long)mp; mp->mib_counters_timer.function = mib_counters_timer_wrapper; mp->mib_counters_timer.expires = jiffies + 30 * HZ; - add_timer(&mp->mib_counters_timer); spin_lock_init(&mp->mib_counters_lock); |