diff options
author | Arnd Bergmann <arnd@arndb.de> | 2012-05-16 16:35:25 +0200 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2012-05-16 16:35:25 +0200 |
commit | 3c0dec5f58b3c7b3627715126d1bf9b030a076f0 (patch) | |
tree | 4bf8f56fca3bf6be109209b116fc8e32cb2e0f9e /drivers/net/ethernet/marvell | |
parent | fcd8d84a585f3578a9ebdd27e757495a27415322 (diff) | |
parent | 7e0fa1b5fa91d9aa456d102c273b2cf0f2e95d39 (diff) |
Merge branch 'clk-next' of git://git.linaro.org/people/mturquette/linux into next/clock
* 'clk-next' of git://git.linaro.org/people/mturquette/linux:
clk: Fix CLK_SET_RATE_GATE flag validation in clk_set_rate().
clk: Provide dummy clk_unregister()
ARM: Kirkwood: Replace clock gating
ARM: Orion: Audio: Add clk/clkdev support
ARM: Orion: PCIE: Add support for clk
ARM: Orion: XOR: Add support for clk
ARM: Orion: CESA: Add support for clk
ARM: Orion: SDIO: Add support for clk.
ARM: Orion: NAND: Add support for clk, if there is one.
ARM: Orion: EHCI: Add support for enabling clocks
ARM: Orion: SATA: Add per channel clk/clkdev support.
ARM: Orion: UART: Get the clock rate via clk_get_rate().
ARM: Orion: WDT: Add clk/clkdev support
ARM: Orion: Eth: Add clk/clkdev support.
ARM: Orion: SPI: Add clk/clkdev support.
ARM: Orion: Add clocks using the generic clk infrastructure.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/net/ethernet/marvell')
-rw-r--r-- | drivers/net/ethernet/marvell/mv643xx_eth.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index 5e1ca0f05090..99cd233266ac 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -57,6 +57,7 @@ #include <linux/types.h> #include <linux/inet_lro.h> #include <linux/slab.h> +#include <linux/clk.h> static char mv643xx_eth_driver_name[] = "mv643xx_eth"; static char mv643xx_eth_driver_version[] = "1.4"; @@ -289,10 +290,10 @@ struct mv643xx_eth_shared_private { /* * Hardware-specific parameters. */ - unsigned int t_clk; int extended_rx_coal_limit; int tx_bw_control; int tx_csum_limit; + }; #define TX_BW_CONTROL_ABSENT 0 @@ -431,6 +432,12 @@ struct mv643xx_eth_private { int tx_desc_sram_size; int txq_count; struct tx_queue txq[8]; + + /* + * Hardware-specific parameters. + */ + struct clk *clk; + unsigned int t_clk; }; @@ -1010,7 +1017,7 @@ static void tx_set_rate(struct mv643xx_eth_private *mp, int rate, int burst) int mtu; int bucket_size; - token_rate = ((rate / 1000) * 64) / (mp->shared->t_clk / 1000); + token_rate = ((rate / 1000) * 64) / (mp->t_clk / 1000); if (token_rate > 1023) token_rate = 1023; @@ -1042,7 +1049,7 @@ static void txq_set_rate(struct tx_queue *txq, int rate, int burst) int token_rate; int bucket_size; - token_rate = ((rate / 1000) * 64) / (mp->shared->t_clk / 1000); + token_rate = ((rate / 1000) * 64) / (mp->t_clk / 1000); if (token_rate > 1023) token_rate = 1023; @@ -1309,7 +1316,7 @@ static unsigned int get_rx_coal(struct mv643xx_eth_private *mp) temp = (val & 0x003fff00) >> 8; temp *= 64000000; - do_div(temp, mp->shared->t_clk); + do_div(temp, mp->t_clk); return (unsigned int)temp; } @@ -1319,7 +1326,7 @@ static void set_rx_coal(struct mv643xx_eth_private *mp, unsigned int usec) u64 temp; u32 val; - temp = (u64)usec * mp->shared->t_clk; + temp = (u64)usec * mp->t_clk; temp += 31999999; do_div(temp, 64000000); @@ -1345,7 +1352,7 @@ static unsigned int get_tx_coal(struct mv643xx_eth_private *mp) temp = (rdlp(mp, TX_FIFO_URGENT_THRESHOLD) & 0x3fff0) >> 4; temp *= 64000000; - do_div(temp, mp->shared->t_clk); + do_div(temp, mp->t_clk); return (unsigned int)temp; } @@ -1354,7 +1361,7 @@ static void set_tx_coal(struct mv643xx_eth_private *mp, unsigned int usec) { u64 temp; - temp = (u64)usec * mp->shared->t_clk; + temp = (u64)usec * mp->t_clk; temp += 31999999; do_div(temp, 64000000); @@ -2662,10 +2669,6 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev) if (dram) mv643xx_eth_conf_mbus_windows(msp, dram); - /* - * Detect hardware parameters. - */ - msp->t_clk = (pd != NULL && pd->t_clk != 0) ? pd->t_clk : 133000000; msp->tx_csum_limit = (pd != NULL && pd->tx_csum_limit) ? pd->tx_csum_limit : 9 * 1024; infer_hw_params(msp); @@ -2890,6 +2893,18 @@ static int mv643xx_eth_probe(struct platform_device *pdev) mp->dev = dev; + /* + * Get the clk rate, if there is one, otherwise use the default. + */ + mp->clk = clk_get(&pdev->dev, (pdev->id ? "1" : "0")); + if (!IS_ERR(mp->clk)) { + clk_prepare_enable(mp->clk); + mp->t_clk = clk_get_rate(mp->clk); + } else { + mp->t_clk = 133000000; + printk(KERN_WARNING "Unable to get clock"); + } + set_params(mp, pd); netif_set_real_num_tx_queues(dev, mp->txq_count); netif_set_real_num_rx_queues(dev, mp->rxq_count); @@ -2978,6 +2993,11 @@ static int mv643xx_eth_remove(struct platform_device *pdev) if (mp->phy != NULL) phy_detach(mp->phy); cancel_work_sync(&mp->tx_timeout_task); + + if (!IS_ERR(mp->clk)) { + clk_disable_unprepare(mp->clk); + clk_put(mp->clk); + } free_netdev(mp->dev); platform_set_drvdata(pdev, NULL); |