* [PATCH net-next v2 07/10] forcedeth: account for dropped RX frames
From: David Decotigny @ 2011-11-11 1:31 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: David S. Miller, Ian Campbell, Eric Dumazet, Jeff Kirsher,
Ben Hutchings, Jiri Pirko, Joe Perches, Szymon Janc,
David Decotigny
In-Reply-To: <cover.1320974990.git.david.decotigny@google.com>
This adds the stats counter for dropped RX frames.
Signed-off-by: David Decotigny <david.decotigny@google.com>
---
drivers/net/ethernet/nvidia/forcedeth.c | 12 ++++++++++--
1 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index cabc121..0a979b8 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -824,6 +824,7 @@ struct fe_priv {
/* RX software stats */
struct nv_driver_stat stat_rx_bytes; /* not always available in HW */
struct nv_driver_stat stat_rx_missed_errors;
+ struct nv_driver_stat stat_rx_dropped;
/* media detection workaround.
* Locking: Within irq hander or disable_irq+spin_lock(&np->lock);
@@ -1738,6 +1739,7 @@ static void nv_update_stats(struct net_device *dev)
/* update software stats */
NV_DRIVER_STAT_UPDATE_TOTAL(&np->stat_rx_bytes);
NV_DRIVER_STAT_UPDATE_TOTAL(&np->stat_rx_missed_errors);
+ NV_DRIVER_STAT_UPDATE_TOTAL(&np->stat_rx_dropped);
NV_DRIVER_STAT_UPDATE_TOTAL(&np->stat_tx_packets);
NV_DRIVER_STAT_UPDATE_TOTAL(&np->stat_tx_dropped);
@@ -1780,6 +1782,8 @@ nv_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *storage)
storage->tx_bytes = np->estats.tx_bytes;
storage->rx_errors = np->estats.rx_errors_total;
storage->tx_errors = np->estats.tx_errors_total;
+ storage->rx_dropped = NV_DRIVER_STAT_GET_TOTAL(
+ &np->stat_rx_dropped);
storage->tx_dropped = NV_DRIVER_STAT_GET_TOTAL(
&np->stat_tx_dropped);
@@ -1835,8 +1839,10 @@ static int nv_alloc_rx(struct net_device *dev)
np->put_rx.orig = np->first_rx.orig;
if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx))
np->put_rx_ctx = np->first_rx_ctx;
- } else
+ } else {
+ NV_DRIVER_STAT_ATOMIC_INC(&np->stat_rx_dropped);
return 1;
+ }
}
return 0;
}
@@ -1867,8 +1873,10 @@ static int nv_alloc_rx_optimized(struct net_device *dev)
np->put_rx.ex = np->first_rx.ex;
if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx))
np->put_rx_ctx = np->first_rx_ctx;
- } else
+ } else {
+ NV_DRIVER_STAT_ATOMIC_INC(&np->stat_rx_dropped);
return 1;
+ }
}
return 0;
}
--
1.7.3.1
^ permalink raw reply related
* [PATCH net-next v2 10/10] forcedeth: whitespace/indentation fixes
From: David Decotigny @ 2011-11-11 1:31 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: David S. Miller, Ian Campbell, Eric Dumazet, Jeff Kirsher,
Ben Hutchings, Jiri Pirko, Joe Perches, Szymon Janc,
David Decotigny
In-Reply-To: <cover.1320974990.git.david.decotigny@google.com>
Signed-off-by: David Decotigny <david.decotigny@google.com>
---
drivers/net/ethernet/nvidia/forcedeth.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index 3617ba3..332a6a6 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -65,7 +65,7 @@
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/prefetch.h>
-#include <linux/io.h>
+#include <linux/io.h>
#include <asm/irq.h>
#include <asm/system.h>
--
1.7.3.1
^ permalink raw reply related
* [PATCH net-next v2 09/10] forcedeth: stats updated with a deferrable timer
From: David Decotigny @ 2011-11-11 1:31 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: David S. Miller, Ian Campbell, Eric Dumazet, Jeff Kirsher,
Ben Hutchings, Jiri Pirko, Joe Perches, Szymon Janc,
David Decotigny
In-Reply-To: <cover.1320974990.git.david.decotigny@google.com>
Mark stats timer as deferrable: punctuality in waking the stats timer
callback doesn't matter much, as it is responsible only to avoid
integer wraparound.
We need at least 1 other timer to fire within 17s (fully loaded 1Gbps)
to avoid wrap-arounds. Desired period is still 10s.
Signed-off-by: David Decotigny <david.decotigny@google.com>
---
drivers/net/ethernet/nvidia/forcedeth.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index 7813c37..3617ba3 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -5377,7 +5377,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
init_timer(&np->nic_poll);
np->nic_poll.data = (unsigned long) dev;
np->nic_poll.function = nv_do_nic_poll; /* timer handler */
- init_timer(&np->stats_poll);
+ init_timer_deferrable(&np->stats_poll);
np->stats_poll.data = (unsigned long) dev;
np->stats_poll.function = nv_do_stats_poll; /* timer handler */
--
1.7.3.1
^ permalink raw reply related
* [PATCH net-next v2 08/10] forcedeth: new ethtool stat counter for TX timeouts
From: David Decotigny @ 2011-11-11 1:31 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: David S. Miller, Ian Campbell, Eric Dumazet, Jeff Kirsher,
Ben Hutchings, Jiri Pirko, Joe Perches, Szymon Janc,
David Decotigny
In-Reply-To: <cover.1320974990.git.david.decotigny@google.com>
This change publishes a new ethtool stats: tx_timeout that counts the
number of times the tx_timeout callback was triggered.
Signed-off-by: David Decotigny <david.decotigny@google.com>
---
drivers/net/ethernet/nvidia/forcedeth.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index 0a979b8..7813c37 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -634,6 +634,7 @@ static const struct nv_ethtool_str nv_estats_str[] = {
{ "rx_packets" },
{ "rx_errors_total" },
{ "tx_errors_total" },
+ { "tx_timeout" },
/* version 2 stats */
{ "tx_deferral" },
@@ -674,6 +675,7 @@ struct nv_ethtool_stats {
u64 rx_packets;
u64 rx_errors_total;
u64 tx_errors_total;
+ u64 tx_timeout;
/* version 2 stats */
u64 tx_deferral;
@@ -851,6 +853,7 @@ struct fe_priv {
/* TX software stats */
struct nv_driver_stat stat_tx_packets; /* not always available in HW */
struct nv_driver_stat stat_tx_dropped;
+ atomic_t stat_tx_timeout; /* TX timeouts since last nv_update_stats */
/* msi/msi-x fields */
u32 msi_flags;
@@ -1743,6 +1746,7 @@ static void nv_update_stats(struct net_device *dev)
NV_DRIVER_STAT_UPDATE_TOTAL(&np->stat_tx_packets);
NV_DRIVER_STAT_UPDATE_TOTAL(&np->stat_tx_dropped);
+ np->estats.tx_timeout += atomic_xchg(&np->stat_tx_timeout, 0);
}
/*
@@ -2624,6 +2628,8 @@ static void nv_tx_timeout(struct net_device *dev)
}
}
+ atomic_inc(&np->stat_tx_timeout);
+
spin_lock_irq(&np->lock);
/* 1) stop tx engine */
--
1.7.3.1
^ permalink raw reply related
* [PATCH net-next v2 06/10] forcedeth: implement ndo_get_stats64() API
From: David Decotigny @ 2011-11-11 1:31 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: David S. Miller, Ian Campbell, Eric Dumazet, Jeff Kirsher,
Ben Hutchings, Jiri Pirko, Joe Perches, Szymon Janc,
David Decotigny
In-Reply-To: <cover.1320974990.git.david.decotigny@google.com>
This commit implements the ndo_get_stats64() API for forcedeth. Since
these stats are being updated from different contexts (process and
timer), this commit adds protection (locking + atomic variables).
Tested:
16-way SMP x86_64 ->
RX bytes:7244556582 (7.2 GB) TX bytes:181904254 (181.9 MB)
Signed-off-by: David Decotigny <david.decotigny@google.com>
---
drivers/net/ethernet/nvidia/forcedeth.c | 155 +++++++++++++++++++++++--------
1 files changed, 118 insertions(+), 37 deletions(-)
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index 1a1972b..cabc121 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -693,6 +693,21 @@ struct nv_ethtool_stats {
#define NV_DEV_STATISTICS_V2_COUNT (NV_DEV_STATISTICS_V3_COUNT - 3)
#define NV_DEV_STATISTICS_V1_COUNT (NV_DEV_STATISTICS_V2_COUNT - 6)
+/* driver statistics */
+struct nv_driver_stat {
+ atomic_t delta; /* increase since last nv_update_stats() */
+ u64 total; /* cumulative, requires netdev_priv(dev)->stats_lock */
+};
+
+#define NV_DRIVER_STAT_ATOMIC_INC(ptr_stat) /* atomic */ \
+ ({ atomic_inc(&(ptr_stat)->delta); })
+#define NV_DRIVER_STAT_ATOMIC_ADD(ptr_stat,increment) /* atomic */ \
+ ({ atomic_add((increment), &(ptr_stat)->delta); })
+#define NV_DRIVER_STAT_UPDATE_TOTAL(ptr_stat) /* requires stats_lock */ \
+ ({ (ptr_stat)->total += atomic_xchg(&(ptr_stat)->delta, 0); })
+#define NV_DRIVER_STAT_GET_TOTAL(ptr_stat) /* requires stats_lock */ \
+ ((ptr_stat)->total)
+
/* diagnostics */
#define NV_TEST_COUNT_BASE 3
#define NV_TEST_COUNT_EXTENDED 4
@@ -737,6 +752,12 @@ struct nv_skb_map {
* - tx setup is lockless: it relies on netif_tx_lock. Actual submission
* needs netdev_priv(dev)->lock :-(
* - set_multicast_list: preparation lockless, relies on netif_tx_lock.
+ *
+ * Stats are protected with stats_lock:
+ * - updated by nv_do_stats_poll (timer). This is meant to avoid
+ * integer wraparound in the NIC stats registers, at low frequency
+ * (0.1 Hz)
+ * - updated by nv_get_ethtool_stats + nv_get_stats64
*/
/* in dev: base, irq */
@@ -746,9 +767,10 @@ struct fe_priv {
struct net_device *dev;
struct napi_struct napi;
- /* General data:
- * Locking: spin_lock(&np->lock); */
+ /* stats are updated in syscall and timer */
+ spinlock_t stats_lock;
struct nv_ethtool_stats estats;
+
int in_shutdown;
u32 linkspeed;
int duplex;
@@ -799,6 +821,10 @@ struct fe_priv {
u32 nic_poll_irq;
int rx_ring_size;
+ /* RX software stats */
+ struct nv_driver_stat stat_rx_bytes; /* not always available in HW */
+ struct nv_driver_stat stat_rx_missed_errors;
+
/* media detection workaround.
* Locking: Within irq hander or disable_irq+spin_lock(&np->lock);
*/
@@ -821,6 +847,10 @@ struct fe_priv {
struct nv_skb_map *tx_end_flip;
int tx_stop;
+ /* TX software stats */
+ struct nv_driver_stat stat_tx_packets; /* not always available in HW */
+ struct nv_driver_stat stat_tx_dropped;
+
/* msi/msi-x fields */
u32 msi_flags;
struct msix_entry msi_x_entry[NV_MSI_X_MAX_VECTORS];
@@ -1636,11 +1666,19 @@ static void nv_mac_reset(struct net_device *dev)
pci_push(base);
}
-static void nv_get_hw_stats(struct net_device *dev)
+/* Caller must appropriately lock netdev_priv(dev)->stats_lock */
+static void nv_update_stats(struct net_device *dev)
{
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
+ /* If it happens that this is run in top-half context, then
+ * replace the spin_lock of stats_lock with
+ * spin_lock_irqsave() in calling functions. */
+ WARN_ONCE(in_irq(), "forcedeth: estats spin_lock(_bh) from top-half");
+ assert_spin_locked(&np->stats_lock);
+
+ /* query hardware */
np->estats.tx_bytes += readl(base + NvRegTxCnt);
np->estats.tx_zero_rexmt += readl(base + NvRegTxZeroReXmt);
np->estats.tx_one_rexmt += readl(base + NvRegTxOneReXmt);
@@ -1696,44 +1734,75 @@ static void nv_get_hw_stats(struct net_device *dev)
np->estats.tx_multicast += readl(base + NvRegTxMulticast);
np->estats.tx_broadcast += readl(base + NvRegTxBroadcast);
}
+
+ /* update software stats */
+ NV_DRIVER_STAT_UPDATE_TOTAL(&np->stat_rx_bytes);
+ NV_DRIVER_STAT_UPDATE_TOTAL(&np->stat_rx_missed_errors);
+
+ NV_DRIVER_STAT_UPDATE_TOTAL(&np->stat_tx_packets);
+ NV_DRIVER_STAT_UPDATE_TOTAL(&np->stat_tx_dropped);
}
/*
- * nv_get_stats: dev->get_stats function
+ * nv_get_stats64: dev->ndo_get_stats64 function
* Get latest stats value from the nic.
* Called with read_lock(&dev_base_lock) held for read -
* only synchronized against unregister_netdevice.
*/
-static struct net_device_stats *nv_get_stats(struct net_device *dev)
+static struct rtnl_link_stats64*
+nv_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *storage)
+ __acquires(&netdev_priv(dev)->stats_lock)
+ __releases(&netdev_priv(dev)->stats_lock)
{
struct fe_priv *np = netdev_priv(dev);
/* If the nic supports hw counters then retrieve latest values */
if (np->driver_data & DEV_HAS_STATISTICS_V123) {
- /* query hardware */
- nv_get_hw_stats(dev);
+ spin_lock_bh(&np->stats_lock);
- /* copy to net_device stats */
+ nv_update_stats(dev);
+
+ /* generic stats */
if (np->driver_data & DEV_HAS_STATISTICS_V23) {
/* When HW stats are available for following
* stats, we use them. Otherwise they are
* updated by software. */
- dev->stats.tx_packets = np->estats.tx_packets;
- dev->stats.rx_bytes = np->estats.rx_bytes;
+ storage->tx_packets = np->estats.tx_packets;
+ storage->rx_bytes = np->estats.rx_bytes;
+ } else {
+ storage->tx_packets = NV_DRIVER_STAT_GET_TOTAL(
+ &np->stat_tx_packets);
+ storage->rx_bytes = NV_DRIVER_STAT_GET_TOTAL(
+ &np->stat_rx_bytes);
}
- dev->stats.rx_packets = np->estats.rx_packets;
- dev->stats.tx_bytes = np->estats.tx_bytes;
- dev->stats.tx_fifo_errors = np->estats.tx_fifo_errors;
- dev->stats.tx_carrier_errors = np->estats.tx_carrier_errors;
- dev->stats.rx_crc_errors = np->estats.rx_crc_errors;
- dev->stats.rx_over_errors = np->estats.rx_over_errors;
- dev->stats.rx_fifo_errors = np->estats.rx_drop_frame;
- dev->stats.rx_errors = np->estats.rx_errors_total;
- dev->stats.tx_errors = np->estats.tx_errors_total;
- }
-
- return &dev->stats;
+ storage->rx_packets = np->estats.rx_packets;
+ storage->tx_bytes = np->estats.tx_bytes;
+ storage->rx_errors = np->estats.rx_errors_total;
+ storage->tx_errors = np->estats.tx_errors_total;
+ storage->tx_dropped = NV_DRIVER_STAT_GET_TOTAL(
+ &np->stat_tx_dropped);
+
+ /* meaningful only when NIC supports stats v3 */
+ storage->multicast = np->estats.rx_multicast;
+
+ /* detailed rx_errors */
+ storage->rx_length_errors = np->estats.rx_length_error;
+ storage->rx_over_errors = np->estats.rx_over_errors;
+ storage->rx_crc_errors = np->estats.rx_crc_errors;
+ storage->rx_frame_errors = np->estats.rx_frame_align_error;
+ storage->rx_fifo_errors = np->estats.rx_drop_frame;
+ storage->rx_missed_errors = NV_DRIVER_STAT_GET_TOTAL(
+ &np->stat_rx_missed_errors);
+
+ /* detailed tx_errors */
+ storage->tx_carrier_errors = np->estats.tx_carrier_errors;
+ storage->tx_fifo_errors = np->estats.tx_fifo_errors;
+
+ spin_unlock_bh(&np->stats_lock);
+ }
+
+ return storage;
}
/*
@@ -1935,7 +2004,7 @@ static void nv_drain_tx(struct net_device *dev)
np->tx_ring.ex[i].buflow = 0;
}
if (nv_release_txskb(np, &np->tx_skb[i]))
- dev->stats.tx_dropped++;
+ NV_DRIVER_STAT_ATOMIC_INC(&np->stat_tx_dropped);
np->tx_skb[i].dma = 0;
np->tx_skb[i].dma_len = 0;
np->tx_skb[i].dma_single = 0;
@@ -2397,7 +2466,7 @@ static int nv_tx_done(struct net_device *dev, int limit)
nv_legacybackoff_reseed(dev);
} else if (unlikely(!(np->driver_data
& DEV_HAS_STATISTICS_V23))) {
- dev->stats.tx_packets++;
+ NV_DRIVER_STAT_ATOMIC_INC(&np->stat_tx_packets);
}
dev_kfree_skb_any(np->get_tx_ctx->skb);
np->get_tx_ctx->skb = NULL;
@@ -2411,7 +2480,7 @@ static int nv_tx_done(struct net_device *dev, int limit)
nv_legacybackoff_reseed(dev);
} else if (unlikely(!(np->driver_data
& DEV_HAS_STATISTICS_V23))) {
- dev->stats.tx_packets++;
+ NV_DRIVER_STAT_ATOMIC_INC(&np->stat_tx_packets);
}
dev_kfree_skb_any(np->get_tx_ctx->skb);
np->get_tx_ctx->skb = NULL;
@@ -2453,7 +2522,7 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit)
}
} else if (unlikely(!(np->driver_data
& DEV_HAS_STATISTICS_V23))) {
- dev->stats.tx_packets++;
+ NV_DRIVER_STAT_ATOMIC_INC(&np->stat_tx_packets);
}
dev_kfree_skb_any(np->get_tx_ctx->skb);
@@ -2667,7 +2736,7 @@ static int nv_rx_process(struct net_device *dev, int limit)
/* the rest are hard errors */
else {
if (flags & NV_RX_MISSEDFRAME)
- dev->stats.rx_missed_errors++;
+ NV_DRIVER_STAT_ATOMIC_INC(&np->stat_rx_missed_errors);
dev_kfree_skb(skb);
goto next_pkt;
}
@@ -2711,7 +2780,7 @@ static int nv_rx_process(struct net_device *dev, int limit)
skb->protocol = eth_type_trans(skb, dev);
napi_gro_receive(&np->napi, skb);
if (unlikely(!(np->driver_data & DEV_HAS_STATISTICS_V23)))
- dev->stats.rx_bytes += len;
+ NV_DRIVER_STAT_ATOMIC_ADD(&np->stat_rx_bytes, len);
next_pkt:
if (unlikely(np->get_rx.orig++ == np->last_rx.orig))
np->get_rx.orig = np->first_rx.orig;
@@ -2796,7 +2865,7 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
napi_gro_receive(&np->napi, skb);
if (unlikely(!(np->driver_data
& DEV_HAS_STATISTICS_V23)))
- dev->stats.rx_bytes += len;
+ NV_DRIVER_STAT_ATOMIC_ADD(&np->stat_rx_bytes, len);
} else {
dev_kfree_skb(skb);
}
@@ -3924,11 +3993,18 @@ static void nv_poll_controller(struct net_device *dev)
#endif
static void nv_do_stats_poll(unsigned long data)
+ __acquires(&netdev_priv(dev)->stats_lock)
+ __releases(&netdev_priv(dev)->stats_lock)
{
struct net_device *dev = (struct net_device *) data;
struct fe_priv *np = netdev_priv(dev);
- nv_get_hw_stats(dev);
+ /* If lock is currently taken, the stats are being refreshed
+ * and hence fresh enough */
+ if (spin_trylock(&np->stats_lock)) {
+ nv_update_stats(dev);
+ spin_unlock(&np->stats_lock);
+ }
if (!np->in_shutdown)
mod_timer(&np->stats_poll,
@@ -4573,14 +4649,18 @@ static int nv_get_sset_count(struct net_device *dev, int sset)
}
}
-static void nv_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *estats, u64 *buffer)
+static void nv_get_ethtool_stats(struct net_device *dev,
+ struct ethtool_stats *estats, u64 *buffer)
+ __acquires(&netdev_priv(dev)->stats_lock)
+ __releases(&netdev_priv(dev)->stats_lock)
{
struct fe_priv *np = netdev_priv(dev);
- /* update stats */
- nv_get_hw_stats(dev);
-
- memcpy(buffer, &np->estats, nv_get_sset_count(dev, ETH_SS_STATS)*sizeof(u64));
+ spin_lock_bh(&np->stats_lock);
+ nv_update_stats(dev);
+ memcpy(buffer, &np->estats,
+ nv_get_sset_count(dev, ETH_SS_STATS)*sizeof(u64));
+ spin_unlock_bh(&np->stats_lock);
}
static int nv_link_test(struct net_device *dev)
@@ -5218,7 +5298,7 @@ static int nv_close(struct net_device *dev)
static const struct net_device_ops nv_netdev_ops = {
.ndo_open = nv_open,
.ndo_stop = nv_close,
- .ndo_get_stats = nv_get_stats,
+ .ndo_get_stats64 = nv_get_stats64,
.ndo_start_xmit = nv_start_xmit,
.ndo_tx_timeout = nv_tx_timeout,
.ndo_change_mtu = nv_change_mtu,
@@ -5235,7 +5315,7 @@ static const struct net_device_ops nv_netdev_ops = {
static const struct net_device_ops nv_netdev_ops_optimized = {
.ndo_open = nv_open,
.ndo_stop = nv_close,
- .ndo_get_stats = nv_get_stats,
+ .ndo_get_stats64 = nv_get_stats64,
.ndo_start_xmit = nv_start_xmit_optimized,
.ndo_tx_timeout = nv_tx_timeout,
.ndo_change_mtu = nv_change_mtu,
@@ -5274,6 +5354,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
np->dev = dev;
np->pci_dev = pci_dev;
spin_lock_init(&np->lock);
+ spin_lock_init(&np->stats_lock);
SET_NETDEV_DEV(dev, &pci_dev->dev);
init_timer(&np->oom_kick);
--
1.7.3.1
^ permalink raw reply related
* [PATCH net-next v2 05/10] forcedeth: stats for rx_packets based on hardware registers
From: David Decotigny @ 2011-11-11 1:31 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: David S. Miller, Ian Campbell, Eric Dumazet, Jeff Kirsher,
Ben Hutchings, Jiri Pirko, Joe Perches, Szymon Janc,
David Decotigny
In-Reply-To: <cover.1320974990.git.david.decotigny@google.com>
Use the hardware registers instead of a software implementation to
account for the number of RX packets.
Signed-off-by: David Decotigny <david.decotigny@google.com>
---
drivers/net/ethernet/nvidia/forcedeth.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index 10d1e37..1a1972b 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -1722,6 +1722,7 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev)
dev->stats.tx_packets = np->estats.tx_packets;
dev->stats.rx_bytes = np->estats.rx_bytes;
}
+ dev->stats.rx_packets = np->estats.rx_packets;
dev->stats.tx_bytes = np->estats.tx_bytes;
dev->stats.tx_fifo_errors = np->estats.tx_fifo_errors;
dev->stats.tx_carrier_errors = np->estats.tx_carrier_errors;
@@ -2709,7 +2710,6 @@ static int nv_rx_process(struct net_device *dev, int limit)
skb_put(skb, len);
skb->protocol = eth_type_trans(skb, dev);
napi_gro_receive(&np->napi, skb);
- dev->stats.rx_packets++;
if (unlikely(!(np->driver_data & DEV_HAS_STATISTICS_V23)))
dev->stats.rx_bytes += len;
next_pkt:
@@ -2794,7 +2794,6 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
__vlan_hwaccel_put_tag(skb, vid);
}
napi_gro_receive(&np->napi, skb);
- dev->stats.rx_packets++;
if (unlikely(!(np->driver_data
& DEV_HAS_STATISTICS_V23)))
dev->stats.rx_bytes += len;
--
1.7.3.1
^ permalink raw reply related
* [PATCH net-next v2 04/10] forcedeth: expose module parameters in /sys/module
From: David Decotigny @ 2011-11-11 1:31 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: David S. Miller, Ian Campbell, Eric Dumazet, Jeff Kirsher,
Ben Hutchings, Jiri Pirko, Joe Perches, Szymon Janc,
David Decotigny
In-Reply-To: <cover.1320974990.git.david.decotigny@google.com>
In particular, debug_tx_timeout can be updated at runtime.
Signed-off-by: David Decotigny <david.decotigny@google.com>
---
drivers/net/ethernet/nvidia/forcedeth.c | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index a6045c5..10d1e37 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -6005,23 +6005,23 @@ static void __exit exit_nic(void)
pci_unregister_driver(&driver);
}
-module_param(max_interrupt_work, int, 0);
+module_param(max_interrupt_work, int, S_IRUGO);
MODULE_PARM_DESC(max_interrupt_work, "forcedeth maximum events handled per interrupt");
-module_param(optimization_mode, int, 0);
+module_param(optimization_mode, int, S_IRUGO);
MODULE_PARM_DESC(optimization_mode, "In throughput mode (0), every tx & rx packet will generate an interrupt. In CPU mode (1), interrupts are controlled by a timer. In dynamic mode (2), the mode toggles between throughput and CPU mode based on network load.");
-module_param(poll_interval, int, 0);
+module_param(poll_interval, int, S_IRUGO);
MODULE_PARM_DESC(poll_interval, "Interval determines how frequent timer interrupt is generated by [(time_in_micro_secs * 100) / (2^10)]. Min is 0 and Max is 65535.");
-module_param(msi, int, 0);
+module_param(msi, int, S_IRUGO);
MODULE_PARM_DESC(msi, "MSI interrupts are enabled by setting to 1 and disabled by setting to 0.");
-module_param(msix, int, 0);
+module_param(msix, int, S_IRUGO);
MODULE_PARM_DESC(msix, "MSIX interrupts are enabled by setting to 1 and disabled by setting to 0.");
-module_param(dma_64bit, int, 0);
+module_param(dma_64bit, int, S_IRUGO);
MODULE_PARM_DESC(dma_64bit, "High DMA is enabled by setting to 1 and disabled by setting to 0.");
-module_param(phy_cross, int, 0);
+module_param(phy_cross, int, S_IRUGO);
MODULE_PARM_DESC(phy_cross, "Phy crossover detection for Realtek 8201 phy is enabled by setting to 1 and disabled by setting to 0.");
-module_param(phy_power_down, int, 0);
+module_param(phy_power_down, int, S_IRUGO);
MODULE_PARM_DESC(phy_power_down, "Power down phy and disable link when interface is down (1), or leave phy powered up (0).");
-module_param(debug_tx_timeout, bool, 0);
+module_param(debug_tx_timeout, bool, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(debug_tx_timeout,
"Dump tx related registers and ring when tx_timeout happens");
--
1.7.3.1
^ permalink raw reply related
* [PATCH net-next v2 03/10] forcedeth: allow to silence "TX timeout" debug messages
From: David Decotigny @ 2011-11-11 1:31 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: David S. Miller, Ian Campbell, Eric Dumazet, Jeff Kirsher,
Ben Hutchings, Jiri Pirko, Joe Perches, Szymon Janc, Sameer Nanda,
David Decotigny
In-Reply-To: <cover.1320974990.git.david.decotigny@google.com>
From: Sameer Nanda <snanda@google.com>
This adds a new module parameter "debug_tx_timeout" to silence most
debug messages in case of TX timeout. These messages don't provide a
signal/noise ratio high enough for production systems and, with ~30kB
logged each time, they tend to add to a cascade effect if the system
is already under stress (memory pressure, disk, etc.).
By default, the parameter is clear, meaning that only a single warning
will be reported.
Signed-off-by: David Decotigny <david.decotigny@google.com>
---
drivers/net/ethernet/nvidia/forcedeth.c | 98 ++++++++++++++++++-------------
1 files changed, 57 insertions(+), 41 deletions(-)
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index af285ac..a6045c5 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -893,6 +893,11 @@ enum {
static int dma_64bit = NV_DMA_64BIT_ENABLED;
/*
+ * Debug output control for tx_timeout
+ */
+static bool debug_tx_timeout = false;
+
+/*
* Crossover Detection
* Realtek 8201 phy + some OEM boards do not work properly.
*/
@@ -2480,56 +2485,64 @@ static void nv_tx_timeout(struct net_device *dev)
u32 status;
union ring_type put_tx;
int saved_tx_limit;
- int i;
if (np->msi_flags & NV_MSI_X_ENABLED)
status = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK;
else
status = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK;
- netdev_info(dev, "Got tx_timeout. irq: %08x\n", status);
+ netdev_warn(dev, "Got tx_timeout. irq status: %08x\n", status);
- netdev_info(dev, "Ring at %lx\n", (unsigned long)np->ring_addr);
- netdev_info(dev, "Dumping tx registers\n");
- for (i = 0; i <= np->register_size; i += 32) {
- netdev_info(dev,
- "%3x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
- i,
- readl(base + i + 0), readl(base + i + 4),
- readl(base + i + 8), readl(base + i + 12),
- readl(base + i + 16), readl(base + i + 20),
- readl(base + i + 24), readl(base + i + 28));
- }
- netdev_info(dev, "Dumping tx ring\n");
- for (i = 0; i < np->tx_ring_size; i += 4) {
- if (!nv_optimized(np)) {
- netdev_info(dev,
- "%03x: %08x %08x // %08x %08x // %08x %08x // %08x %08x\n",
- i,
- le32_to_cpu(np->tx_ring.orig[i].buf),
- le32_to_cpu(np->tx_ring.orig[i].flaglen),
- le32_to_cpu(np->tx_ring.orig[i+1].buf),
- le32_to_cpu(np->tx_ring.orig[i+1].flaglen),
- le32_to_cpu(np->tx_ring.orig[i+2].buf),
- le32_to_cpu(np->tx_ring.orig[i+2].flaglen),
- le32_to_cpu(np->tx_ring.orig[i+3].buf),
- le32_to_cpu(np->tx_ring.orig[i+3].flaglen));
- } else {
+ if (unlikely(debug_tx_timeout)) {
+ int i;
+
+ netdev_info(dev, "Ring at %lx\n", (unsigned long)np->ring_addr);
+ netdev_info(dev, "Dumping tx registers\n");
+ for (i = 0; i <= np->register_size; i += 32) {
netdev_info(dev,
- "%03x: %08x %08x %08x // %08x %08x %08x // %08x %08x %08x // %08x %08x %08x\n",
+ "%3x: %08x %08x %08x %08x "
+ "%08x %08x %08x %08x\n",
i,
- le32_to_cpu(np->tx_ring.ex[i].bufhigh),
- le32_to_cpu(np->tx_ring.ex[i].buflow),
- le32_to_cpu(np->tx_ring.ex[i].flaglen),
- le32_to_cpu(np->tx_ring.ex[i+1].bufhigh),
- le32_to_cpu(np->tx_ring.ex[i+1].buflow),
- le32_to_cpu(np->tx_ring.ex[i+1].flaglen),
- le32_to_cpu(np->tx_ring.ex[i+2].bufhigh),
- le32_to_cpu(np->tx_ring.ex[i+2].buflow),
- le32_to_cpu(np->tx_ring.ex[i+2].flaglen),
- le32_to_cpu(np->tx_ring.ex[i+3].bufhigh),
- le32_to_cpu(np->tx_ring.ex[i+3].buflow),
- le32_to_cpu(np->tx_ring.ex[i+3].flaglen));
+ readl(base + i + 0), readl(base + i + 4),
+ readl(base + i + 8), readl(base + i + 12),
+ readl(base + i + 16), readl(base + i + 20),
+ readl(base + i + 24), readl(base + i + 28));
+ }
+ netdev_info(dev, "Dumping tx ring\n");
+ for (i = 0; i < np->tx_ring_size; i += 4) {
+ if (!nv_optimized(np)) {
+ netdev_info(dev,
+ "%03x: %08x %08x // %08x %08x "
+ "// %08x %08x // %08x %08x\n",
+ i,
+ le32_to_cpu(np->tx_ring.orig[i].buf),
+ le32_to_cpu(np->tx_ring.orig[i].flaglen),
+ le32_to_cpu(np->tx_ring.orig[i+1].buf),
+ le32_to_cpu(np->tx_ring.orig[i+1].flaglen),
+ le32_to_cpu(np->tx_ring.orig[i+2].buf),
+ le32_to_cpu(np->tx_ring.orig[i+2].flaglen),
+ le32_to_cpu(np->tx_ring.orig[i+3].buf),
+ le32_to_cpu(np->tx_ring.orig[i+3].flaglen));
+ } else {
+ netdev_info(dev,
+ "%03x: %08x %08x %08x "
+ "// %08x %08x %08x "
+ "// %08x %08x %08x "
+ "// %08x %08x %08x\n",
+ i,
+ le32_to_cpu(np->tx_ring.ex[i].bufhigh),
+ le32_to_cpu(np->tx_ring.ex[i].buflow),
+ le32_to_cpu(np->tx_ring.ex[i].flaglen),
+ le32_to_cpu(np->tx_ring.ex[i+1].bufhigh),
+ le32_to_cpu(np->tx_ring.ex[i+1].buflow),
+ le32_to_cpu(np->tx_ring.ex[i+1].flaglen),
+ le32_to_cpu(np->tx_ring.ex[i+2].bufhigh),
+ le32_to_cpu(np->tx_ring.ex[i+2].buflow),
+ le32_to_cpu(np->tx_ring.ex[i+2].flaglen),
+ le32_to_cpu(np->tx_ring.ex[i+3].bufhigh),
+ le32_to_cpu(np->tx_ring.ex[i+3].buflow),
+ le32_to_cpu(np->tx_ring.ex[i+3].flaglen));
+ }
}
}
@@ -6008,6 +6021,9 @@ module_param(phy_cross, int, 0);
MODULE_PARM_DESC(phy_cross, "Phy crossover detection for Realtek 8201 phy is enabled by setting to 1 and disabled by setting to 0.");
module_param(phy_power_down, int, 0);
MODULE_PARM_DESC(phy_power_down, "Power down phy and disable link when interface is down (1), or leave phy powered up (0).");
+module_param(debug_tx_timeout, bool, 0);
+MODULE_PARM_DESC(debug_tx_timeout,
+ "Dump tx related registers and ring when tx_timeout happens");
MODULE_AUTHOR("Manfred Spraul <manfred@colorfullife.com>");
MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver");
--
1.7.3.1
^ permalink raw reply related
* [PATCH net-next v2 02/10] forcedeth: Add messages to indicate using MSI or MSI-X
From: David Decotigny @ 2011-11-11 1:31 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: David S. Miller, Ian Campbell, Eric Dumazet, Jeff Kirsher,
Ben Hutchings, Jiri Pirko, Joe Perches, Szymon Janc, Mike Ditto,
David Decotigny
In-Reply-To: <cover.1320974990.git.david.decotigny@google.com>
From: Mike Ditto <mditto@google.com>
This adds a few debug messages to indicate whether PCIe interrupts are
signaled with MSI or MSI-X.
Signed-off-by: David Decotigny <david.decotigny@google.com>
---
drivers/net/ethernet/nvidia/forcedeth.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index 6e5213e..af285ac 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -3735,6 +3735,7 @@ static int nv_request_irq(struct net_device *dev, int intr_test)
writel(0, base + NvRegMSIXMap0);
writel(0, base + NvRegMSIXMap1);
}
+ netdev_info(dev, "MSI-X enabled\n");
}
}
if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) {
@@ -3756,6 +3757,7 @@ static int nv_request_irq(struct net_device *dev, int intr_test)
writel(0, base + NvRegMSIMap1);
/* enable msi vector 0 */
writel(NVREG_MSI_VECTOR_0_ENABLED, base + NvRegMSIIrqMask);
+ netdev_info(dev, "MSI enabled\n");
}
}
if (ret != 0) {
--
1.7.3.1
^ permalink raw reply related
* [PATCH net-next v2 01/10] forcedeth: fix ifconfig stats on hardware without extended stats support
From: David Decotigny @ 2011-11-11 1:31 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: David S. Miller, Ian Campbell, Eric Dumazet, Jeff Kirsher,
Ben Hutchings, Jiri Pirko, Joe Perches, Szymon Janc,
David Decotigny
In-Reply-To: <cover.1320974990.git.david.decotigny@google.com>
This change makes sure that tx_packets/rx_bytes ifconfig counters are
updated even on NICs that don't provide hardware support for these
stats. In that case, they are updated in software.
Related commit: "forcedeth: Improve stats counters" (0bdfea8ba8)
Signed-off-by: David Decotigny <david.decotigny@google.com>
---
drivers/net/ethernet/nvidia/forcedeth.c | 34 ++++++++++++++++++++++++++----
1 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index d24c45b..6e5213e 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -90,6 +90,7 @@
#define DEV_HAS_STATISTICS_V2 0x0000400 /* device supports hw statistics version 2 */
#define DEV_HAS_STATISTICS_V3 0x0000800 /* device supports hw statistics version 3 */
#define DEV_HAS_STATISTICS_V12 0x0000600 /* device supports hw statistics version 1 and 2 */
+#define DEV_HAS_STATISTICS_V23 0x0000c00 /* device supports hw statistics version 2 and 3 */
#define DEV_HAS_STATISTICS_V123 0x0000e00 /* device supports hw statistics version 1, 2, and 3 */
#define DEV_HAS_TEST_EXTENDED 0x0001000 /* device supports extended diagnostic test */
#define DEV_HAS_MGMT_UNIT 0x0002000 /* device supports management unit */
@@ -1703,12 +1704,19 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev)
struct fe_priv *np = netdev_priv(dev);
/* If the nic supports hw counters then retrieve latest values */
- if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_STATISTICS_V3)) {
+ if (np->driver_data & DEV_HAS_STATISTICS_V123) {
+ /* query hardware */
nv_get_hw_stats(dev);
/* copy to net_device stats */
- dev->stats.tx_packets = np->estats.tx_packets;
- dev->stats.rx_bytes = np->estats.rx_bytes;
+
+ if (np->driver_data & DEV_HAS_STATISTICS_V23) {
+ /* When HW stats are available for following
+ * stats, we use them. Otherwise they are
+ * updated by software. */
+ dev->stats.tx_packets = np->estats.tx_packets;
+ dev->stats.rx_bytes = np->estats.rx_bytes;
+ }
dev->stats.tx_bytes = np->estats.tx_bytes;
dev->stats.tx_fifo_errors = np->estats.tx_fifo_errors;
dev->stats.tx_carrier_errors = np->estats.tx_carrier_errors;
@@ -2378,8 +2386,12 @@ static int nv_tx_done(struct net_device *dev, int limit)
if (np->desc_ver == DESC_VER_1) {
if (flags & NV_TX_LASTPACKET) {
if (flags & NV_TX_ERROR) {
- if ((flags & NV_TX_RETRYERROR) && !(flags & NV_TX_RETRYCOUNT_MASK))
+ if ((flags & NV_TX_RETRYERROR)
+ && !(flags & NV_TX_RETRYCOUNT_MASK))
nv_legacybackoff_reseed(dev);
+ } else if (unlikely(!(np->driver_data
+ & DEV_HAS_STATISTICS_V23))) {
+ dev->stats.tx_packets++;
}
dev_kfree_skb_any(np->get_tx_ctx->skb);
np->get_tx_ctx->skb = NULL;
@@ -2388,8 +2400,12 @@ static int nv_tx_done(struct net_device *dev, int limit)
} else {
if (flags & NV_TX2_LASTPACKET) {
if (flags & NV_TX2_ERROR) {
- if ((flags & NV_TX2_RETRYERROR) && !(flags & NV_TX2_RETRYCOUNT_MASK))
+ if ((flags & NV_TX2_RETRYERROR)
+ && !(flags & NV_TX2_RETRYCOUNT_MASK))
nv_legacybackoff_reseed(dev);
+ } else if (unlikely(!(np->driver_data
+ & DEV_HAS_STATISTICS_V23))) {
+ dev->stats.tx_packets++;
}
dev_kfree_skb_any(np->get_tx_ctx->skb);
np->get_tx_ctx->skb = NULL;
@@ -2429,6 +2445,9 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit)
else
nv_legacybackoff_reseed(dev);
}
+ } else if (unlikely(!(np->driver_data
+ & DEV_HAS_STATISTICS_V23))) {
+ dev->stats.tx_packets++;
}
dev_kfree_skb_any(np->get_tx_ctx->skb);
@@ -2678,6 +2697,8 @@ static int nv_rx_process(struct net_device *dev, int limit)
skb->protocol = eth_type_trans(skb, dev);
napi_gro_receive(&np->napi, skb);
dev->stats.rx_packets++;
+ if (unlikely(!(np->driver_data & DEV_HAS_STATISTICS_V23)))
+ dev->stats.rx_bytes += len;
next_pkt:
if (unlikely(np->get_rx.orig++ == np->last_rx.orig))
np->get_rx.orig = np->first_rx.orig;
@@ -2761,6 +2782,9 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
}
napi_gro_receive(&np->napi, skb);
dev->stats.rx_packets++;
+ if (unlikely(!(np->driver_data
+ & DEV_HAS_STATISTICS_V23)))
+ dev->stats.rx_bytes += len;
} else {
dev_kfree_skb(skb);
}
--
1.7.3.1
^ permalink raw reply related
* [PATCH V2 12/14] net: fec: add clk_prepare/clk_unprepare
From: Richard Zhao @ 2011-11-11 1:10 UTC (permalink / raw)
To: linux-arm-kernel, linux-i2c, linux-mmc, netdev, linux-serial
Cc: linux, amit.kucheria, kernel, ben-linux, cjb, alan, eric.miao,
Richard Zhao
In-Reply-To: <1320973829-4388-1-git-send-email-richard.zhao@linaro.org>
Signed-off-by: Richard Zhao <richard.zhao@linaro.org>
---
drivers/net/ethernet/freescale/fec.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index 1124ce0..e96fa44 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -1588,7 +1588,7 @@ fec_probe(struct platform_device *pdev)
ret = PTR_ERR(fep->clk);
goto failed_clk;
}
- clk_enable(fep->clk);
+ clk_prepare_enable(fep->clk);
ret = fec_enet_init(ndev);
if (ret)
@@ -1611,7 +1611,7 @@ failed_register:
fec_enet_mii_remove(fep);
failed_mii_init:
failed_init:
- clk_disable(fep->clk);
+ clk_disable_unprepare(fep->clk);
clk_put(fep->clk);
failed_clk:
for (i = 0; i < FEC_IRQ_NUM; i++) {
@@ -1638,7 +1638,7 @@ fec_drv_remove(struct platform_device *pdev)
fec_stop(ndev);
fec_enet_mii_remove(fep);
- clk_disable(fep->clk);
+ clk_disable_unprepare(fep->clk);
clk_put(fep->clk);
iounmap(fep->hwp);
unregister_netdev(ndev);
@@ -1664,7 +1664,7 @@ fec_suspend(struct device *dev)
fec_stop(ndev);
netif_device_detach(ndev);
}
- clk_disable(fep->clk);
+ clk_disable_unprepare(fep->clk);
return 0;
}
@@ -1675,7 +1675,7 @@ fec_resume(struct device *dev)
struct net_device *ndev = dev_get_drvdata(dev);
struct fec_enet_private *fep = netdev_priv(ndev);
- clk_enable(fep->clk);
+ clk_prepare_enable(fep->clk);
if (netif_running(ndev)) {
fec_restart(ndev, fep->full_duplex);
netif_device_attach(ndev);
--
1.7.5.4
^ permalink raw reply related
* [PATCH V2 11/14] serial: imx: add clk_prepare/clk_unprepare
From: Richard Zhao @ 2011-11-11 1:10 UTC (permalink / raw)
To: linux-arm-kernel, linux-i2c, linux-mmc, netdev, linux-serial
Cc: linux, amit.kucheria, kernel, ben-linux, cjb, alan, eric.miao,
Richard Zhao
In-Reply-To: <1320973829-4388-1-git-send-email-richard.zhao@linaro.org>
Signed-off-by: Richard Zhao <richard.zhao@linaro.org>
---
drivers/tty/serial/imx.c | 7 +++----
1 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 163fc90..8f3709f 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1390,7 +1390,7 @@ static int serial_imx_probe(struct platform_device *pdev)
ret = PTR_ERR(sport->clk);
goto unmap;
}
- clk_enable(sport->clk);
+ clk_prepare_enable(sport->clk);
sport->port.uartclk = clk_get_rate(sport->clk);
@@ -1413,8 +1413,8 @@ deinit:
if (pdata && pdata->exit)
pdata->exit(pdev);
clkput:
+ clk_disable_unprepare(sport->clk);
clk_put(sport->clk);
- clk_disable(sport->clk);
unmap:
iounmap(sport->port.membase);
free:
@@ -1434,11 +1434,10 @@ static int serial_imx_remove(struct platform_device *pdev)
if (sport) {
uart_remove_one_port(&imx_reg, &sport->port);
+ clk_disable_unprepare(sport->clk);
clk_put(sport->clk);
}
- clk_disable(sport->clk);
-
if (pdata && pdata->exit)
pdata->exit(pdev);
--
1.7.5.4
^ permalink raw reply related
* [PATCH V2 10/14] ARM: mxs: add clk_prepare/clk_unprepare
From: Richard Zhao @ 2011-11-11 1:10 UTC (permalink / raw)
To: linux-arm-kernel, linux-i2c, linux-mmc, netdev, linux-serial
Cc: linux, amit.kucheria, kernel, ben-linux, cjb, alan, eric.miao,
Richard Zhao
In-Reply-To: <1320973829-4388-1-git-send-email-richard.zhao@linaro.org>
Signed-off-by: Richard Zhao <richard.zhao@linaro.org>
---
arch/arm/mach-mxs/system.c | 2 +-
arch/arm/mach-mxs/timer.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
index 20ec3bd..9760a12 100644
--- a/arch/arm/mach-mxs/system.c
+++ b/arch/arm/mach-mxs/system.c
@@ -66,7 +66,7 @@ static int __init mxs_arch_reset_init(void)
clk = clk_get_sys("rtc", NULL);
if (!IS_ERR(clk))
- clk_enable(clk);
+ clk_prepare_enable(clk);
return 0;
}
diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
index cace0d2..564a632 100644
--- a/arch/arm/mach-mxs/timer.c
+++ b/arch/arm/mach-mxs/timer.c
@@ -245,7 +245,7 @@ static int __init mxs_clocksource_init(struct clk *timer_clk)
void __init mxs_timer_init(struct clk *timer_clk, int irq)
{
- clk_enable(timer_clk);
+ clk_prepare_enable(timer_clk);
/*
* Initialize timers to a known state
--
1.7.5.4
^ permalink raw reply related
* [PATCH V2 07/14] ARM: mxc: audmux-v2: add clk_prepare/clk_unprepare
From: Richard Zhao @ 2011-11-11 1:10 UTC (permalink / raw)
To: linux-arm-kernel, linux-i2c, linux-mmc, netdev, linux-serial
Cc: linux, amit.kucheria, kernel, ben-linux, cjb, alan, eric.miao,
Richard Zhao
In-Reply-To: <1320973829-4388-1-git-send-email-richard.zhao@linaro.org>
Signed-off-by: Richard Zhao <richard.zhao@linaro.org>
---
arch/arm/plat-mxc/audmux-v2.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/plat-mxc/audmux-v2.c b/arch/arm/plat-mxc/audmux-v2.c
index 8cced35..0e51fc3 100644
--- a/arch/arm/plat-mxc/audmux-v2.c
+++ b/arch/arm/plat-mxc/audmux-v2.c
@@ -73,13 +73,13 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
return -ENOMEM;
if (audmux_clk)
- clk_enable(audmux_clk);
+ clk_prepare_enable(audmux_clk);
ptcr = readl(audmux_base + MXC_AUDMUX_V2_PTCR(port));
pdcr = readl(audmux_base + MXC_AUDMUX_V2_PDCR(port));
if (audmux_clk)
- clk_disable(audmux_clk);
+ clk_disable_unprepare(audmux_clk);
ret = snprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n",
pdcr, ptcr);
@@ -172,13 +172,13 @@ int mxc_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
return -ENOSYS;
if (audmux_clk)
- clk_enable(audmux_clk);
+ clk_prepare_enable(audmux_clk);
writel(ptcr, audmux_base + MXC_AUDMUX_V2_PTCR(port));
writel(pdcr, audmux_base + MXC_AUDMUX_V2_PDCR(port));
if (audmux_clk)
- clk_disable(audmux_clk);
+ clk_disable_unprepare(audmux_clk);
return 0;
}
--
1.7.5.4
^ permalink raw reply related
* [PATCH V2 14/14] mmc: sdhci-esdhc-imx: add clk_prepare/clk_unprepare
From: Richard Zhao @ 2011-11-11 1:10 UTC (permalink / raw)
To: linux-arm-kernel, linux-i2c, linux-mmc, netdev, linux-serial
Cc: amit.kucheria, linux, kernel, eric.miao, ben-linux, cjb,
Richard Zhao, alan
In-Reply-To: <1320973829-4388-1-git-send-email-richard.zhao@linaro.org>
Signed-off-by: Richard Zhao <richard.zhao@linaro.org>
---
drivers/mmc/host/sdhci-esdhc-imx.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index ae57769..f1ae37e 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -462,7 +462,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
err = PTR_ERR(clk);
goto err_clk_get;
}
- clk_enable(clk);
+ clk_prepare_enable(clk);
pltfm_host->clk = clk;
if (!is_imx25_esdhc(imx_data))
@@ -550,7 +550,7 @@ no_card_detect_irq:
gpio_free(boarddata->wp_gpio);
no_card_detect_pin:
no_board_data:
- clk_disable(pltfm_host->clk);
+ clk_disable_unprepare(pltfm_host->clk);
clk_put(pltfm_host->clk);
err_clk_get:
kfree(imx_data);
@@ -577,7 +577,7 @@ static int __devexit sdhci_esdhc_imx_remove(struct platform_device *pdev)
gpio_free(boarddata->cd_gpio);
}
- clk_disable(pltfm_host->clk);
+ clk_disable_unprepare(pltfm_host->clk);
clk_put(pltfm_host->clk);
kfree(imx_data);
--
1.7.5.4
^ permalink raw reply related
* [PATCH V2 13/14] i2c: imx: add clk_prepare/clk_unprepare
From: Richard Zhao @ 2011-11-11 1:10 UTC (permalink / raw)
To: linux-arm-kernel, linux-i2c, linux-mmc, netdev, linux-serial
Cc: amit.kucheria, linux, kernel, eric.miao, ben-linux, cjb,
Richard Zhao, alan
In-Reply-To: <1320973829-4388-1-git-send-email-richard.zhao@linaro.org>
Signed-off-by: Richard Zhao <richard.zhao@linaro.org>
---
drivers/i2c/busses/i2c-imx.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 58832e5..8d1ab6f 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -196,7 +196,7 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
- clk_enable(i2c_imx->clk);
+ clk_prepare_enable(i2c_imx->clk);
writeb(i2c_imx->ifdr, i2c_imx->base + IMX_I2C_IFDR);
/* Enable I2C controller */
writeb(0, i2c_imx->base + IMX_I2C_I2SR);
@@ -245,7 +245,7 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
/* Disable I2C controller */
writeb(0, i2c_imx->base + IMX_I2C_I2CR);
- clk_disable(i2c_imx->clk);
+ clk_disable_unprepare(i2c_imx->clk);
}
static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
--
1.7.5.4
^ permalink raw reply related
* [PATCH V2 09/14] ARM: mx31moboard: add clk_prepare/clk_unprepare
From: Richard Zhao @ 2011-11-11 1:10 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ,
amit.kucheria-Z7WLFzj8eWMS+FvcfC7Uqw,
kernel-bIcnvbaLZ9MEGnE8C9+IrQ, ben-linux-elnMNo+KYs3YtjvyW6yDsg,
cjb-2X9k7bc8m7Mdnm+yROfE0A, alan-VuQAYsv1563Yd54FQh9/CA,
eric.miao-QSEj5FYQhm4dnm+yROfE0A, Richard Zhao
In-Reply-To: <1320973829-4388-1-git-send-email-richard.zhao-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Richard Zhao <richard.zhao-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
arch/arm/mach-imx/mach-mx31moboard.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c
index 07034f4..d1a9337 100644
--- a/arch/arm/mach-imx/mach-mx31moboard.c
+++ b/arch/arm/mach-imx/mach-mx31moboard.c
@@ -505,7 +505,7 @@ static void mx31moboard_poweroff(void)
struct clk *clk = clk_get_sys("imx2-wdt.0", NULL);
if (!IS_ERR(clk))
- clk_enable(clk);
+ clk_prepare_enable(clk);
mxc_iomux_mode(MX31_PIN_WATCHDOG_RST__WATCHDOG_RST);
--
1.7.5.4
^ permalink raw reply related
* [PATCH V2 08/14] ARM: pm-imx5: add clk_prepare/clk_unprepare
From: Richard Zhao @ 2011-11-11 1:10 UTC (permalink / raw)
To: linux-arm-kernel, linux-i2c, linux-mmc, netdev, linux-serial
Cc: amit.kucheria, linux, kernel, eric.miao, ben-linux, cjb,
Richard Zhao, alan
In-Reply-To: <1320973829-4388-1-git-send-email-richard.zhao@linaro.org>
Signed-off-by: Richard Zhao <richard.zhao@linaro.org>
---
arch/arm/mach-mx5/pm-imx5.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-mx5/pm-imx5.c b/arch/arm/mach-mx5/pm-imx5.c
index 98052fc..2bdc85f 100644
--- a/arch/arm/mach-mx5/pm-imx5.c
+++ b/arch/arm/mach-mx5/pm-imx5.c
@@ -22,7 +22,7 @@ static struct clk *gpc_dvfs_clk;
static int mx5_suspend_prepare(void)
{
- return clk_enable(gpc_dvfs_clk);
+ return clk_prepare_enable(gpc_dvfs_clk);
}
static int mx5_suspend_enter(suspend_state_t state)
@@ -52,7 +52,7 @@ static int mx5_suspend_enter(suspend_state_t state)
static void mx5_suspend_finish(void)
{
- clk_disable(gpc_dvfs_clk);
+ clk_disable_unprepare(gpc_dvfs_clk);
}
static int mx5_pm_valid(suspend_state_t state)
--
1.7.5.4
^ permalink raw reply related
* [PATCH] ip6_tunnel: copy parms.name after register_netdevice
From: Josh Boyer @ 2011-11-11 1:10 UTC (permalink / raw)
To: Jiri Pirko, David S. Miller; +Cc: netdev, linux-kernel, stable
Commit 1c5cae815d removed an explicit call to dev_alloc_name in ip6_tnl_create
because register_netdevice will now create a valid name. This works for the
net_device itself.
However the tunnel keeps a copy of the name in the parms structure for the
ip6_tnl associated with the tunnel. parms.name is set by copying the net_device
name in ip6_tnl_dev_init_gen. That function is called from ip6_tnl_dev_init in
ip6_tnl_create, but it is done before register_netdevice is called so the name
is set to a bogus value in the parms.name structure.
This shows up if you do a simple tunnel add, followed by a tunnel show:
[root@localhost ~]# ip -6 tunnel add remote fec0::100 local fec0::200
[root@localhost ~]# ip -6 tunnel show
ip6tnl0: ipv6/ipv6 remote :: local :: encaplimit 0 hoplimit 0 tclass 0x00 flowlabel 0x00000 (flowinfo 0x00000000)
ip6tnl%d: ipv6/ipv6 remote fec0::100 local fec0::200 encaplimit 4 hoplimit 64 tclass 0x00 flowlabel 0x00000 (flowinfo 0x00000000)
[root@localhost ~]#
Fix this by moving the strcpy out of ip6_tnl_dev_init_gen, and calling it after
register_netdevice has successfully returned.
Cc: stable@vger.kernel.org
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
---
net/ipv6/ip6_tunnel.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index bdc15c9..09b50d6 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -288,6 +288,8 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p)
if ((err = register_netdevice(dev)) < 0)
goto failed_free;
+
+ strcpy(t->parms.name, dev->name);
dev_hold(dev);
ip6_tnl_link(ip6n, t);
@@ -1407,7 +1409,6 @@ ip6_tnl_dev_init_gen(struct net_device *dev)
struct ip6_tnl *t = netdev_priv(dev);
t->dev = dev;
- strcpy(t->parms.name, dev->name);
dev->tstats = alloc_percpu(struct pcpu_tstats);
if (!dev->tstats)
return -ENOMEM;
@@ -1487,6 +1488,7 @@ static void __net_exit ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n)
static int __net_init ip6_tnl_init_net(struct net *net)
{
struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
+ struct ip6_tnl *t = NULL;
int err;
ip6n->tnls[0] = ip6n->tnls_wc;
@@ -1507,6 +1509,10 @@ static int __net_init ip6_tnl_init_net(struct net *net)
err = register_netdev(ip6n->fb_tnl_dev);
if (err < 0)
goto err_register;
+
+ t = netdev_priv(ip6n->fb_tnl_dev);
+
+ strcpy(t->parms.name, ip6n->fb_tnl_dev->name);
return 0;
err_register:
--
1.7.7
^ permalink raw reply related
* [PATCH V2 06/14] ARM: mxc: arch_reset: add clk_prepare/clk_unprepare
From: Richard Zhao @ 2011-11-11 1:10 UTC (permalink / raw)
To: linux-arm-kernel, linux-i2c, linux-mmc, netdev, linux-serial
Cc: linux, amit.kucheria, kernel, ben-linux, cjb, alan, eric.miao,
Richard Zhao
In-Reply-To: <1320973829-4388-1-git-send-email-richard.zhao@linaro.org>
Signed-off-by: Richard Zhao <richard.zhao@linaro.org>
---
arch/arm/plat-mxc/system.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/plat-mxc/system.c b/arch/arm/plat-mxc/system.c
index 9dad8dc..a667adc 100644
--- a/arch/arm/plat-mxc/system.c
+++ b/arch/arm/plat-mxc/system.c
@@ -54,7 +54,7 @@ void arch_reset(char mode, const char *cmd)
clk = clk_get_sys("imx2-wdt.0", NULL);
if (!IS_ERR(clk))
- clk_enable(clk);
+ clk_prepare_enable(clk);
wcr_enable = (1 << 2);
}
--
1.7.5.4
^ permalink raw reply related
* [PATCH V2 05/14] ARM: mxc: epit: add clk_prepare/clk_unprepare
From: Richard Zhao @ 2011-11-11 1:10 UTC (permalink / raw)
To: linux-arm-kernel, linux-i2c, linux-mmc, netdev, linux-serial
Cc: linux, amit.kucheria, kernel, ben-linux, cjb, alan, eric.miao,
Richard Zhao
In-Reply-To: <1320973829-4388-1-git-send-email-richard.zhao@linaro.org>
Signed-off-by: Richard Zhao <richard.zhao@linaro.org>
---
arch/arm/plat-mxc/epit.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/plat-mxc/epit.c b/arch/arm/plat-mxc/epit.c
index d3467f8..9129c9e 100644
--- a/arch/arm/plat-mxc/epit.c
+++ b/arch/arm/plat-mxc/epit.c
@@ -203,7 +203,7 @@ static int __init epit_clockevent_init(struct clk *timer_clk)
void __init epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
{
- clk_enable(timer_clk);
+ clk_prepare_enable(timer_clk);
timer_base = base;
--
1.7.5.4
^ permalink raw reply related
* [PATCH V2 04/14] ARM: mxc: pwm: add clk_prepare/clk_unprepare
From: Richard Zhao @ 2011-11-11 1:10 UTC (permalink / raw)
To: linux-arm-kernel, linux-i2c, linux-mmc, netdev, linux-serial
Cc: amit.kucheria, linux, kernel, eric.miao, ben-linux, cjb,
Richard Zhao, alan
In-Reply-To: <1320973829-4388-1-git-send-email-richard.zhao@linaro.org>
Signed-off-by: Richard Zhao <richard.zhao@linaro.org>
---
arch/arm/plat-mxc/pwm.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/plat-mxc/pwm.c b/arch/arm/plat-mxc/pwm.c
index 42d74ea..68c7199b 100644
--- a/arch/arm/plat-mxc/pwm.c
+++ b/arch/arm/plat-mxc/pwm.c
@@ -118,7 +118,7 @@ int pwm_enable(struct pwm_device *pwm)
int rc = 0;
if (!pwm->clk_enabled) {
- rc = clk_enable(pwm->clk);
+ rc = clk_prepare_enable(pwm->clk);
if (!rc)
pwm->clk_enabled = 1;
}
@@ -131,7 +131,7 @@ void pwm_disable(struct pwm_device *pwm)
writel(0, pwm->mmio_base + MX3_PWMCR);
if (pwm->clk_enabled) {
- clk_disable(pwm->clk);
+ clk_disable_unprepare(pwm->clk);
pwm->clk_enabled = 0;
}
}
--
1.7.5.4
^ permalink raw reply related
* [PATCH V2 03/14] ARM: mxc: ahci: add clk_prepare/clk_unprepare
From: Richard Zhao @ 2011-11-11 1:10 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ,
amit.kucheria-Z7WLFzj8eWMS+FvcfC7Uqw,
kernel-bIcnvbaLZ9MEGnE8C9+IrQ, ben-linux-elnMNo+KYs3YtjvyW6yDsg,
cjb-2X9k7bc8m7Mdnm+yROfE0A, alan-VuQAYsv1563Yd54FQh9/CA,
eric.miao-QSEj5FYQhm4dnm+yROfE0A, Richard Zhao
In-Reply-To: <1320973829-4388-1-git-send-email-richard.zhao-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Richard Zhao <richard.zhao-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
arch/arm/plat-mxc/devices/platform-ahci-imx.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/arm/plat-mxc/devices/platform-ahci-imx.c b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
index d8a56ae..ade4a1c 100644
--- a/arch/arm/plat-mxc/devices/platform-ahci-imx.c
+++ b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
@@ -60,9 +60,9 @@ static int imx_sata_init(struct device *dev, void __iomem *addr)
dev_err(dev, "no sata clock.\n");
return PTR_ERR(sata_clk);
}
- ret = clk_enable(sata_clk);
+ ret = clk_prepare_enable(sata_clk);
if (ret) {
- dev_err(dev, "can't enable sata clock.\n");
+ dev_err(dev, "can't prepare/enable sata clock.\n");
goto put_sata_clk;
}
@@ -73,9 +73,9 @@ static int imx_sata_init(struct device *dev, void __iomem *addr)
ret = PTR_ERR(sata_ref_clk);
goto release_sata_clk;
}
- ret = clk_enable(sata_ref_clk);
+ ret = clk_prepare_enable(sata_ref_clk);
if (ret) {
- dev_err(dev, "can't enable sata ref clock.\n");
+ dev_err(dev, "can't prepare/enable sata ref clock.\n");
goto put_sata_ref_clk;
}
@@ -104,11 +104,11 @@ static int imx_sata_init(struct device *dev, void __iomem *addr)
return 0;
release_sata_ref_clk:
- clk_disable(sata_ref_clk);
+ clk_disable_unprepare(sata_ref_clk);
put_sata_ref_clk:
clk_put(sata_ref_clk);
release_sata_clk:
- clk_disable(sata_clk);
+ clk_disable_unprepare(sata_clk);
put_sata_clk:
clk_put(sata_clk);
@@ -117,10 +117,10 @@ put_sata_clk:
static void imx_sata_exit(struct device *dev)
{
- clk_disable(sata_ref_clk);
+ clk_disable_unprepare(sata_ref_clk);
clk_put(sata_ref_clk);
- clk_disable(sata_clk);
+ clk_disable_unprepare(sata_clk);
clk_put(sata_clk);
}
--
1.7.5.4
^ permalink raw reply related
* [PATCH V2 02/14] ARM: mxc: time: add clk_prepare/clk_unprepare
From: Richard Zhao @ 2011-11-11 1:10 UTC (permalink / raw)
To: linux-arm-kernel, linux-i2c, linux-mmc, netdev, linux-serial
Cc: linux, amit.kucheria, kernel, ben-linux, cjb, alan, eric.miao,
Richard Zhao
In-Reply-To: <1320973829-4388-1-git-send-email-richard.zhao@linaro.org>
Signed-off-by: Richard Zhao <richard.zhao@linaro.org>
---
arch/arm/plat-mxc/time.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
index 4b0fe28..b4e8b18 100644
--- a/arch/arm/plat-mxc/time.c
+++ b/arch/arm/plat-mxc/time.c
@@ -292,7 +292,7 @@ void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
{
uint32_t tctl_val;
- clk_enable(timer_clk);
+ clk_prepare_enable(timer_clk);
timer_base = base;
--
1.7.5.4
^ permalink raw reply related
* [PATCH V2 01/14] clk: add helper functions clk_prepare_enable and clk_disable_unprepare
From: Richard Zhao @ 2011-11-11 1:10 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ,
amit.kucheria-Z7WLFzj8eWMS+FvcfC7Uqw,
kernel-bIcnvbaLZ9MEGnE8C9+IrQ, ben-linux-elnMNo+KYs3YtjvyW6yDsg,
cjb-2X9k7bc8m7Mdnm+yROfE0A, alan-VuQAYsv1563Yd54FQh9/CA,
eric.miao-QSEj5FYQhm4dnm+yROfE0A, Richard Zhao
In-Reply-To: <1320973829-4388-1-git-send-email-richard.zhao-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Richard Zhao <richard.zhao-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
include/linux/clk.h | 19 +++++++++++++++++++
1 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 7213b52..63985f7 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -107,6 +107,25 @@ static inline void clk_unprepare(struct clk *clk)
}
#endif
+static inline int clk_prepare_enable(struct clk *clk)
+{
+ int ret;
+
+ ret = clk_prepare(clk);
+ if (!ret)
+ ret = clk_enable(clk);
+ if (ret)
+ clk_unprepare(clk);
+
+ return ret;
+}
+
+static inline void clk_disable_unprepare(struct clk *clk)
+{
+ clk_disable(clk);
+ clk_unprepare(clk);
+}
+
/**
* clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
* This is only valid once the clock source has been enabled.
--
1.7.5.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox