diff options
author | David S. Miller <davem@davemloft.net> | 2013-12-10 22:56:31 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-10 22:56:31 -0500 |
commit | 4ba3f99a3624187f47f160234fc49a3b8054a0c1 (patch) | |
tree | 68977e7fae1bdb561770f5ae0590951fda62e72c | |
parent | fa08943b975c08697e57aff26784970dd0dd926a (diff) | |
parent | e1824dfe0d8e6bae55859eb016ce21b61d1b8c85 (diff) |
Merge branch 'macb'
From: Soren Brinkmann <soren.brinkmann@xilinx.com>
====================
net: macb updates
I'd really like to have Ethernet working for Zynq, so I want to at least
revive this discussion regarding this patchset. And the first four
patches should not even be too controversial.
I didn't change anything compared to my original RFC submission, except
for a typo in one of the commit messages.
Handling the tx_clk as optional clock input seems a little bit weird,
but it works on my Zynq platform and should be compatible with other
users of macb and their DT descriptions.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/cadence/macb.c | 126 | ||||
-rw-r--r-- | drivers/net/ethernet/cadence/macb.h | 1 |
2 files changed, 98 insertions, 29 deletions
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 92578690f6de..419529a9309d 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/circ_buf.h> | 17 | #include <linux/circ_buf.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/io.h> | ||
20 | #include <linux/gpio.h> | 21 | #include <linux/gpio.h> |
21 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
22 | #include <linux/netdevice.h> | 23 | #include <linux/netdevice.h> |
@@ -203,6 +204,47 @@ static int macb_mdio_reset(struct mii_bus *bus) | |||
203 | return 0; | 204 | return 0; |
204 | } | 205 | } |
205 | 206 | ||
207 | /** | ||
208 | * macb_set_tx_clk() - Set a clock to a new frequency | ||
209 | * @clk Pointer to the clock to change | ||
210 | * @rate New frequency in Hz | ||
211 | * @dev Pointer to the struct net_device | ||
212 | */ | ||
213 | static void macb_set_tx_clk(struct clk *clk, int speed, struct net_device *dev) | ||
214 | { | ||
215 | long ferr, rate, rate_rounded; | ||
216 | |||
217 | switch (speed) { | ||
218 | case SPEED_10: | ||
219 | rate = 2500000; | ||
220 | break; | ||
221 | case SPEED_100: | ||
222 | rate = 25000000; | ||
223 | break; | ||
224 | case SPEED_1000: | ||
225 | rate = 125000000; | ||
226 | break; | ||
227 | default: | ||
228 | break; | ||
229 | } | ||
230 | |||
231 | rate_rounded = clk_round_rate(clk, rate); | ||
232 | if (rate_rounded < 0) | ||
233 | return; | ||
234 | |||
235 | /* RGMII allows 50 ppm frequency error. Test and warn if this limit | ||
236 | * is not satisfied. | ||
237 | */ | ||
238 | ferr = abs(rate_rounded - rate); | ||
239 | ferr = DIV_ROUND_UP(ferr, rate / 100000); | ||
240 | if (ferr > 5) | ||
241 | netdev_warn(dev, "unable to generate target frequency: %ld Hz\n", | ||
242 | rate); | ||
243 | |||
244 | if (clk_set_rate(clk, rate_rounded)) | ||
245 | netdev_err(dev, "adjusting tx_clk failed.\n"); | ||
246 | } | ||
247 | |||
206 | static void macb_handle_link_change(struct net_device *dev) | 248 | static void macb_handle_link_change(struct net_device *dev) |
207 | { | 249 | { |
208 | struct macb *bp = netdev_priv(dev); | 250 | struct macb *bp = netdev_priv(dev); |
@@ -250,6 +292,9 @@ static void macb_handle_link_change(struct net_device *dev) | |||
250 | 292 | ||
251 | spin_unlock_irqrestore(&bp->lock, flags); | 293 | spin_unlock_irqrestore(&bp->lock, flags); |
252 | 294 | ||
295 | if (!IS_ERR(bp->tx_clk)) | ||
296 | macb_set_tx_clk(bp->tx_clk, phydev->speed, dev); | ||
297 | |||
253 | if (status_change) { | 298 | if (status_change) { |
254 | if (phydev->link) { | 299 | if (phydev->link) { |
255 | netif_carrier_on(dev); | 300 | netif_carrier_on(dev); |
@@ -1790,21 +1835,44 @@ static int __init macb_probe(struct platform_device *pdev) | |||
1790 | spin_lock_init(&bp->lock); | 1835 | spin_lock_init(&bp->lock); |
1791 | INIT_WORK(&bp->tx_error_task, macb_tx_error_task); | 1836 | INIT_WORK(&bp->tx_error_task, macb_tx_error_task); |
1792 | 1837 | ||
1793 | bp->pclk = clk_get(&pdev->dev, "pclk"); | 1838 | bp->pclk = devm_clk_get(&pdev->dev, "pclk"); |
1794 | if (IS_ERR(bp->pclk)) { | 1839 | if (IS_ERR(bp->pclk)) { |
1795 | dev_err(&pdev->dev, "failed to get macb_clk\n"); | 1840 | err = PTR_ERR(bp->pclk); |
1841 | dev_err(&pdev->dev, "failed to get macb_clk (%u)\n", err); | ||
1796 | goto err_out_free_dev; | 1842 | goto err_out_free_dev; |
1797 | } | 1843 | } |
1798 | clk_prepare_enable(bp->pclk); | ||
1799 | 1844 | ||
1800 | bp->hclk = clk_get(&pdev->dev, "hclk"); | 1845 | bp->hclk = devm_clk_get(&pdev->dev, "hclk"); |
1801 | if (IS_ERR(bp->hclk)) { | 1846 | if (IS_ERR(bp->hclk)) { |
1802 | dev_err(&pdev->dev, "failed to get hclk\n"); | 1847 | err = PTR_ERR(bp->hclk); |
1803 | goto err_out_put_pclk; | 1848 | dev_err(&pdev->dev, "failed to get hclk (%u)\n", err); |
1849 | goto err_out_free_dev; | ||
1804 | } | 1850 | } |
1805 | clk_prepare_enable(bp->hclk); | ||
1806 | 1851 | ||
1807 | bp->regs = ioremap(regs->start, resource_size(regs)); | 1852 | bp->tx_clk = devm_clk_get(&pdev->dev, "tx_clk"); |
1853 | |||
1854 | err = clk_prepare_enable(bp->pclk); | ||
1855 | if (err) { | ||
1856 | dev_err(&pdev->dev, "failed to enable pclk (%u)\n", err); | ||
1857 | goto err_out_free_dev; | ||
1858 | } | ||
1859 | |||
1860 | err = clk_prepare_enable(bp->hclk); | ||
1861 | if (err) { | ||
1862 | dev_err(&pdev->dev, "failed to enable hclk (%u)\n", err); | ||
1863 | goto err_out_disable_pclk; | ||
1864 | } | ||
1865 | |||
1866 | if (!IS_ERR(bp->tx_clk)) { | ||
1867 | err = clk_prepare_enable(bp->tx_clk); | ||
1868 | if (err) { | ||
1869 | dev_err(&pdev->dev, "failed to enable tx_clk (%u)\n", | ||
1870 | err); | ||
1871 | goto err_out_disable_hclk; | ||
1872 | } | ||
1873 | } | ||
1874 | |||
1875 | bp->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs)); | ||
1808 | if (!bp->regs) { | 1876 | if (!bp->regs) { |
1809 | dev_err(&pdev->dev, "failed to map registers, aborting.\n"); | 1877 | dev_err(&pdev->dev, "failed to map registers, aborting.\n"); |
1810 | err = -ENOMEM; | 1878 | err = -ENOMEM; |
@@ -1812,11 +1880,12 @@ static int __init macb_probe(struct platform_device *pdev) | |||
1812 | } | 1880 | } |
1813 | 1881 | ||
1814 | dev->irq = platform_get_irq(pdev, 0); | 1882 | dev->irq = platform_get_irq(pdev, 0); |
1815 | err = request_irq(dev->irq, macb_interrupt, 0, dev->name, dev); | 1883 | err = devm_request_irq(&pdev->dev, dev->irq, macb_interrupt, 0, |
1884 | dev->name, dev); | ||
1816 | if (err) { | 1885 | if (err) { |
1817 | dev_err(&pdev->dev, "Unable to request IRQ %d (error %d)\n", | 1886 | dev_err(&pdev->dev, "Unable to request IRQ %d (error %d)\n", |
1818 | dev->irq, err); | 1887 | dev->irq, err); |
1819 | goto err_out_iounmap; | 1888 | goto err_out_disable_clocks; |
1820 | } | 1889 | } |
1821 | 1890 | ||
1822 | dev->netdev_ops = &macb_netdev_ops; | 1891 | dev->netdev_ops = &macb_netdev_ops; |
@@ -1879,7 +1948,7 @@ static int __init macb_probe(struct platform_device *pdev) | |||
1879 | err = register_netdev(dev); | 1948 | err = register_netdev(dev); |
1880 | if (err) { | 1949 | if (err) { |
1881 | dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); | 1950 | dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); |
1882 | goto err_out_free_irq; | 1951 | goto err_out_disable_clocks; |
1883 | } | 1952 | } |
1884 | 1953 | ||
1885 | err = macb_mii_init(bp); | 1954 | err = macb_mii_init(bp); |
@@ -1902,16 +1971,13 @@ static int __init macb_probe(struct platform_device *pdev) | |||
1902 | 1971 | ||
1903 | err_out_unregister_netdev: | 1972 | err_out_unregister_netdev: |
1904 | unregister_netdev(dev); | 1973 | unregister_netdev(dev); |
1905 | err_out_free_irq: | ||
1906 | free_irq(dev->irq, dev); | ||
1907 | err_out_iounmap: | ||
1908 | iounmap(bp->regs); | ||
1909 | err_out_disable_clocks: | 1974 | err_out_disable_clocks: |
1975 | if (!IS_ERR(bp->tx_clk)) | ||
1976 | clk_disable_unprepare(bp->tx_clk); | ||
1977 | err_out_disable_hclk: | ||
1910 | clk_disable_unprepare(bp->hclk); | 1978 | clk_disable_unprepare(bp->hclk); |
1911 | clk_put(bp->hclk); | 1979 | err_out_disable_pclk: |
1912 | clk_disable_unprepare(bp->pclk); | 1980 | clk_disable_unprepare(bp->pclk); |
1913 | err_out_put_pclk: | ||
1914 | clk_put(bp->pclk); | ||
1915 | err_out_free_dev: | 1981 | err_out_free_dev: |
1916 | free_netdev(dev); | 1982 | free_netdev(dev); |
1917 | err_out: | 1983 | err_out: |
@@ -1933,12 +1999,10 @@ static int __exit macb_remove(struct platform_device *pdev) | |||
1933 | kfree(bp->mii_bus->irq); | 1999 | kfree(bp->mii_bus->irq); |
1934 | mdiobus_free(bp->mii_bus); | 2000 | mdiobus_free(bp->mii_bus); |
1935 | unregister_netdev(dev); | 2001 | unregister_netdev(dev); |
1936 | free_irq(dev->irq, dev); | 2002 | if (!IS_ERR(bp->tx_clk)) |
1937 | iounmap(bp->regs); | 2003 | clk_disable_unprepare(bp->tx_clk); |
1938 | clk_disable_unprepare(bp->hclk); | 2004 | clk_disable_unprepare(bp->hclk); |
1939 | clk_put(bp->hclk); | ||
1940 | clk_disable_unprepare(bp->pclk); | 2005 | clk_disable_unprepare(bp->pclk); |
1941 | clk_put(bp->pclk); | ||
1942 | free_netdev(dev); | 2006 | free_netdev(dev); |
1943 | } | 2007 | } |
1944 | 2008 | ||
@@ -1946,45 +2010,49 @@ static int __exit macb_remove(struct platform_device *pdev) | |||
1946 | } | 2010 | } |
1947 | 2011 | ||
1948 | #ifdef CONFIG_PM | 2012 | #ifdef CONFIG_PM |
1949 | static int macb_suspend(struct platform_device *pdev, pm_message_t state) | 2013 | static int macb_suspend(struct device *dev) |
1950 | { | 2014 | { |
2015 | struct platform_device *pdev = to_platform_device(dev); | ||
1951 | struct net_device *netdev = platform_get_drvdata(pdev); | 2016 | struct net_device *netdev = platform_get_drvdata(pdev); |
1952 | struct macb *bp = netdev_priv(netdev); | 2017 | struct macb *bp = netdev_priv(netdev); |
1953 | 2018 | ||
1954 | netif_carrier_off(netdev); | 2019 | netif_carrier_off(netdev); |
1955 | netif_device_detach(netdev); | 2020 | netif_device_detach(netdev); |
1956 | 2021 | ||
2022 | if (!IS_ERR(bp->tx_clk)) | ||
2023 | clk_disable_unprepare(bp->tx_clk); | ||
1957 | clk_disable_unprepare(bp->hclk); | 2024 | clk_disable_unprepare(bp->hclk); |
1958 | clk_disable_unprepare(bp->pclk); | 2025 | clk_disable_unprepare(bp->pclk); |
1959 | 2026 | ||
1960 | return 0; | 2027 | return 0; |
1961 | } | 2028 | } |
1962 | 2029 | ||
1963 | static int macb_resume(struct platform_device *pdev) | 2030 | static int macb_resume(struct device *dev) |
1964 | { | 2031 | { |
2032 | struct platform_device *pdev = to_platform_device(dev); | ||
1965 | struct net_device *netdev = platform_get_drvdata(pdev); | 2033 | struct net_device *netdev = platform_get_drvdata(pdev); |
1966 | struct macb *bp = netdev_priv(netdev); | 2034 | struct macb *bp = netdev_priv(netdev); |
1967 | 2035 | ||
1968 | clk_prepare_enable(bp->pclk); | 2036 | clk_prepare_enable(bp->pclk); |
1969 | clk_prepare_enable(bp->hclk); | 2037 | clk_prepare_enable(bp->hclk); |
2038 | if (!IS_ERR(bp->tx_clk)) | ||
2039 | clk_prepare_enable(bp->tx_clk); | ||
1970 | 2040 | ||
1971 | netif_device_attach(netdev); | 2041 | netif_device_attach(netdev); |
1972 | 2042 | ||
1973 | return 0; | 2043 | return 0; |
1974 | } | 2044 | } |
1975 | #else | ||
1976 | #define macb_suspend NULL | ||
1977 | #define macb_resume NULL | ||
1978 | #endif | 2045 | #endif |
1979 | 2046 | ||
2047 | static SIMPLE_DEV_PM_OPS(macb_pm_ops, macb_suspend, macb_resume); | ||
2048 | |||
1980 | static struct platform_driver macb_driver = { | 2049 | static struct platform_driver macb_driver = { |
1981 | .remove = __exit_p(macb_remove), | 2050 | .remove = __exit_p(macb_remove), |
1982 | .suspend = macb_suspend, | ||
1983 | .resume = macb_resume, | ||
1984 | .driver = { | 2051 | .driver = { |
1985 | .name = "macb", | 2052 | .name = "macb", |
1986 | .owner = THIS_MODULE, | 2053 | .owner = THIS_MODULE, |
1987 | .of_match_table = of_match_ptr(macb_dt_ids), | 2054 | .of_match_table = of_match_ptr(macb_dt_ids), |
2055 | .pm = &macb_pm_ops, | ||
1988 | }, | 2056 | }, |
1989 | }; | 2057 | }; |
1990 | 2058 | ||
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index f4076155bed7..51c02442160a 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h | |||
@@ -572,6 +572,7 @@ struct macb { | |||
572 | struct platform_device *pdev; | 572 | struct platform_device *pdev; |
573 | struct clk *pclk; | 573 | struct clk *pclk; |
574 | struct clk *hclk; | 574 | struct clk *hclk; |
575 | struct clk *tx_clk; | ||
575 | struct net_device *dev; | 576 | struct net_device *dev; |
576 | struct napi_struct napi; | 577 | struct napi_struct napi; |
577 | struct work_struct tx_error_task; | 578 | struct work_struct tx_error_task; |