aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/nxp/lpc_eth.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-22 12:30:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-22 12:30:52 -0400
commitb324c67d4800e59171f48d9ddab6cbfb59110482 (patch)
treea16509a710e76fa24c01514b60aed06b7db13716 /drivers/net/ethernet/nxp/lpc_eth.c
parent8dca6010d44cc722a94dc6da96560f9083dac782 (diff)
parent396d81cd0fe12ce5d1f6d159f093f9315d2837bc (diff)
Merge tag 'dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull device tree conversions for arm-soc, part 1, from Olof Johansson: "The spear3xx, lpc32xx, shmobile and mmp platforms are joining the game of booting using device trees, which is a great step forward for them. at91 and spear have pretty much completed this process with a huge amount of work being put into at91. The other platforms are continuing the process. We finally start to see the payback on this investment, as new machines are getting supported purely by adding a .dts source file that can be completely independent of the kernel source." Fix up trivial conflict in arch/arm/Kconfig * tag 'dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (83 commits) ARM: at91: Add ADC driver to at91sam9260/at91sam9g20 dtsi files arm/dts: omap4-panda: Add LEDs support arm/dts: omap4-sdp: Add LEDs support arm/dts: twl4030: Add twl4030-gpio node OMAP4: devices: Do not create mcpdm device if the dtb has been provided OMAP4: devices: Do not create dmic device if the dtb has been provided Documentation: update docs for mmp dt ARM: dts: refresh dts file for arch mmp ARM: mmp: support pxa910 with device tree ARM: mmp: support mmp2 with device tree gpio: pxa: parse gpio from DTS file ARM: mmp: support DT in timer ARM: mmp: support DT in irq ARM: mmp: append CONFIG_MACH_MMP2_DT ARM: mmp: fix build issue on mmp with device tree ARM: ux500: Enable PRCMU Timer 4 (clocksource) for Device Tree ARM: ux500: Disable SMSC911x platform code registration when DT is enabled ARM: ux500: Fork cpu-db8500 platform_devs for sequential DT enablement ARM: ux500: Do not attempt to register non-existent i2c devices on Snowball ARM: SPEAr3xx: Correct keyboard data passed from DT ...
Diffstat (limited to 'drivers/net/ethernet/nxp/lpc_eth.c')
-rw-r--r--drivers/net/ethernet/nxp/lpc_eth.c71
1 files changed, 50 insertions, 21 deletions
diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c
index d3469d8e3f0d..8d2666fcffd7 100644
--- a/drivers/net/ethernet/nxp/lpc_eth.c
+++ b/drivers/net/ethernet/nxp/lpc_eth.c
@@ -40,6 +40,7 @@
40#include <linux/skbuff.h> 40#include <linux/skbuff.h>
41#include <linux/phy.h> 41#include <linux/phy.h>
42#include <linux/dma-mapping.h> 42#include <linux/dma-mapping.h>
43#include <linux/of.h>
43#include <linux/of_net.h> 44#include <linux/of_net.h>
44#include <linux/types.h> 45#include <linux/types.h>
45 46
@@ -340,13 +341,17 @@
340 */ 341 */
341#define LPC_POWERDOWN_MACAHB (1 << 31) 342#define LPC_POWERDOWN_MACAHB (1 << 31)
342 343
343/* Upon the upcoming introduction of device tree usage in LPC32xx, 344static phy_interface_t lpc_phy_interface_mode(struct device *dev)
344 * lpc_phy_interface_mode() and use_iram_for_net() will be extended with a
345 * device parameter for access to device tree information at runtime, instead
346 * of defining the values at compile time
347 */
348static inline phy_interface_t lpc_phy_interface_mode(void)
349{ 345{
346 if (dev && dev->of_node) {
347 const char *mode = of_get_property(dev->of_node,
348 "phy-mode", NULL);
349 if (mode && !strcmp(mode, "mii"))
350 return PHY_INTERFACE_MODE_MII;
351 return PHY_INTERFACE_MODE_RMII;
352 }
353
354 /* non-DT */
350#ifdef CONFIG_ARCH_LPC32XX_MII_SUPPORT 355#ifdef CONFIG_ARCH_LPC32XX_MII_SUPPORT
351 return PHY_INTERFACE_MODE_MII; 356 return PHY_INTERFACE_MODE_MII;
352#else 357#else
@@ -354,12 +359,16 @@ static inline phy_interface_t lpc_phy_interface_mode(void)
354#endif 359#endif
355} 360}
356 361
357static inline int use_iram_for_net(void) 362static bool use_iram_for_net(struct device *dev)
358{ 363{
364 if (dev && dev->of_node)
365 return of_property_read_bool(dev->of_node, "use-iram");
366
367 /* non-DT */
359#ifdef CONFIG_ARCH_LPC32XX_IRAM_FOR_NET 368#ifdef CONFIG_ARCH_LPC32XX_IRAM_FOR_NET
360 return 1; 369 return true;
361#else 370#else
362 return 0; 371 return false;
363#endif 372#endif
364} 373}
365 374
@@ -664,7 +673,7 @@ static void __lpc_eth_init(struct netdata_local *pldat)
664 LPC_ENET_CLRT(pldat->net_base)); 673 LPC_ENET_CLRT(pldat->net_base));
665 writel(LPC_IPGR_LOAD_PART2(0x12), LPC_ENET_IPGR(pldat->net_base)); 674 writel(LPC_IPGR_LOAD_PART2(0x12), LPC_ENET_IPGR(pldat->net_base));
666 675
667 if (lpc_phy_interface_mode() == PHY_INTERFACE_MODE_MII) 676 if (lpc_phy_interface_mode(&pldat->pdev->dev) == PHY_INTERFACE_MODE_MII)
668 writel(LPC_COMMAND_PASSRUNTFRAME, 677 writel(LPC_COMMAND_PASSRUNTFRAME,
669 LPC_ENET_COMMAND(pldat->net_base)); 678 LPC_ENET_COMMAND(pldat->net_base));
670 else { 679 else {
@@ -804,12 +813,13 @@ static int lpc_mii_probe(struct net_device *ndev)
804 } 813 }
805 814
806 /* Attach to the PHY */ 815 /* Attach to the PHY */
807 if (lpc_phy_interface_mode() == PHY_INTERFACE_MODE_MII) 816 if (lpc_phy_interface_mode(&pldat->pdev->dev) == PHY_INTERFACE_MODE_MII)
808 netdev_info(ndev, "using MII interface\n"); 817 netdev_info(ndev, "using MII interface\n");
809 else 818 else
810 netdev_info(ndev, "using RMII interface\n"); 819 netdev_info(ndev, "using RMII interface\n");
811 phydev = phy_connect(ndev, dev_name(&phydev->dev), 820 phydev = phy_connect(ndev, dev_name(&phydev->dev),
812 &lpc_handle_link_change, 0, lpc_phy_interface_mode()); 821 &lpc_handle_link_change, 0,
822 lpc_phy_interface_mode(&pldat->pdev->dev));
813 823
814 if (IS_ERR(phydev)) { 824 if (IS_ERR(phydev)) {
815 netdev_err(ndev, "Could not attach to PHY\n"); 825 netdev_err(ndev, "Could not attach to PHY\n");
@@ -843,7 +853,7 @@ static int lpc_mii_init(struct netdata_local *pldat)
843 } 853 }
844 854
845 /* Setup MII mode */ 855 /* Setup MII mode */
846 if (lpc_phy_interface_mode() == PHY_INTERFACE_MODE_MII) 856 if (lpc_phy_interface_mode(&pldat->pdev->dev) == PHY_INTERFACE_MODE_MII)
847 writel(LPC_COMMAND_PASSRUNTFRAME, 857 writel(LPC_COMMAND_PASSRUNTFRAME,
848 LPC_ENET_COMMAND(pldat->net_base)); 858 LPC_ENET_COMMAND(pldat->net_base));
849 else { 859 else {
@@ -1315,18 +1325,26 @@ static const struct net_device_ops lpc_netdev_ops = {
1315static int lpc_eth_drv_probe(struct platform_device *pdev) 1325static int lpc_eth_drv_probe(struct platform_device *pdev)
1316{ 1326{
1317 struct resource *res; 1327 struct resource *res;
1318 struct resource *dma_res;
1319 struct net_device *ndev; 1328 struct net_device *ndev;
1320 struct netdata_local *pldat; 1329 struct netdata_local *pldat;
1321 struct phy_device *phydev; 1330 struct phy_device *phydev;
1322 dma_addr_t dma_handle; 1331 dma_addr_t dma_handle;
1323 int irq, ret; 1332 int irq, ret;
1333 u32 tmp;
1334
1335 /* Setup network interface for RMII or MII mode */
1336 tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL);
1337 tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK;
1338 if (lpc_phy_interface_mode(&pdev->dev) == PHY_INTERFACE_MODE_MII)
1339 tmp |= LPC32XX_CLKPWR_MACCTRL_USE_MII_PINS;
1340 else
1341 tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS;
1342 __raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL);
1324 1343
1325 /* Get platform resources */ 1344 /* Get platform resources */
1326 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1345 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1327 dma_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1328 irq = platform_get_irq(pdev, 0); 1346 irq = platform_get_irq(pdev, 0);
1329 if ((!res) || (!dma_res) || (irq < 0) || (irq >= NR_IRQS)) { 1347 if ((!res) || (irq < 0) || (irq >= NR_IRQS)) {
1330 dev_err(&pdev->dev, "error getting resources.\n"); 1348 dev_err(&pdev->dev, "error getting resources.\n");
1331 ret = -ENXIO; 1349 ret = -ENXIO;
1332 goto err_exit; 1350 goto err_exit;
@@ -1389,17 +1407,19 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
1389 sizeof(struct txrx_desc_t) + sizeof(struct rx_status_t)); 1407 sizeof(struct txrx_desc_t) + sizeof(struct rx_status_t));
1390 pldat->dma_buff_base_v = 0; 1408 pldat->dma_buff_base_v = 0;
1391 1409
1392 if (use_iram_for_net()) { 1410 if (use_iram_for_net(&pldat->pdev->dev)) {
1393 dma_handle = dma_res->start; 1411 dma_handle = LPC32XX_IRAM_BASE;
1394 if (pldat->dma_buff_size <= lpc32xx_return_iram_size()) 1412 if (pldat->dma_buff_size <= lpc32xx_return_iram_size())
1395 pldat->dma_buff_base_v = 1413 pldat->dma_buff_base_v =
1396 io_p2v(dma_res->start); 1414 io_p2v(LPC32XX_IRAM_BASE);
1397 else 1415 else
1398 netdev_err(ndev, 1416 netdev_err(ndev,
1399 "IRAM not big enough for net buffers, using SDRAM instead.\n"); 1417 "IRAM not big enough for net buffers, using SDRAM instead.\n");
1400 } 1418 }
1401 1419
1402 if (pldat->dma_buff_base_v == 0) { 1420 if (pldat->dma_buff_base_v == 0) {
1421 pldat->pdev->dev.coherent_dma_mask = 0xFFFFFFFF;
1422 pldat->pdev->dev.dma_mask = &pldat->pdev->dev.coherent_dma_mask;
1403 pldat->dma_buff_size = PAGE_ALIGN(pldat->dma_buff_size); 1423 pldat->dma_buff_size = PAGE_ALIGN(pldat->dma_buff_size);
1404 1424
1405 /* Allocate a chunk of memory for the DMA ethernet buffers 1425 /* Allocate a chunk of memory for the DMA ethernet buffers
@@ -1488,7 +1508,7 @@ err_out_unregister_netdev:
1488 platform_set_drvdata(pdev, NULL); 1508 platform_set_drvdata(pdev, NULL);
1489 unregister_netdev(ndev); 1509 unregister_netdev(ndev);
1490err_out_dma_unmap: 1510err_out_dma_unmap:
1491 if (!use_iram_for_net() || 1511 if (!use_iram_for_net(&pldat->pdev->dev) ||
1492 pldat->dma_buff_size > lpc32xx_return_iram_size()) 1512 pldat->dma_buff_size > lpc32xx_return_iram_size())
1493 dma_free_coherent(&pldat->pdev->dev, pldat->dma_buff_size, 1513 dma_free_coherent(&pldat->pdev->dev, pldat->dma_buff_size,
1494 pldat->dma_buff_base_v, 1514 pldat->dma_buff_base_v,
@@ -1515,7 +1535,7 @@ static int lpc_eth_drv_remove(struct platform_device *pdev)
1515 unregister_netdev(ndev); 1535 unregister_netdev(ndev);
1516 platform_set_drvdata(pdev, NULL); 1536 platform_set_drvdata(pdev, NULL);
1517 1537
1518 if (!use_iram_for_net() || 1538 if (!use_iram_for_net(&pldat->pdev->dev) ||
1519 pldat->dma_buff_size > lpc32xx_return_iram_size()) 1539 pldat->dma_buff_size > lpc32xx_return_iram_size())
1520 dma_free_coherent(&pldat->pdev->dev, pldat->dma_buff_size, 1540 dma_free_coherent(&pldat->pdev->dev, pldat->dma_buff_size,
1521 pldat->dma_buff_base_v, 1541 pldat->dma_buff_base_v,
@@ -1584,6 +1604,14 @@ static int lpc_eth_drv_resume(struct platform_device *pdev)
1584} 1604}
1585#endif 1605#endif
1586 1606
1607#ifdef CONFIG_OF
1608static const struct of_device_id lpc_eth_match[] = {
1609 { .compatible = "nxp,lpc-eth" },
1610 { }
1611};
1612MODULE_DEVICE_TABLE(of, lpc_eth_match);
1613#endif
1614
1587static struct platform_driver lpc_eth_driver = { 1615static struct platform_driver lpc_eth_driver = {
1588 .probe = lpc_eth_drv_probe, 1616 .probe = lpc_eth_drv_probe,
1589 .remove = __devexit_p(lpc_eth_drv_remove), 1617 .remove = __devexit_p(lpc_eth_drv_remove),
@@ -1593,6 +1621,7 @@ static struct platform_driver lpc_eth_driver = {
1593#endif 1621#endif
1594 .driver = { 1622 .driver = {
1595 .name = MODNAME, 1623 .name = MODNAME,
1624 .of_match_table = of_match_ptr(lpc_eth_match),
1596 }, 1625 },
1597}; 1626};
1598 1627