.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Intel IXP4xx Ethernet driver for Linux |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2007 Krzysztof Halasa <khc@pm.waw.pl> |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify it |
---|
7 | | - * under the terms of version 2 of the GNU General Public License |
---|
8 | | - * as published by the Free Software Foundation. |
---|
9 | 6 | * |
---|
10 | 7 | * Ethernet port config (0x00 is not present on IXP42X): |
---|
11 | 8 | * |
---|
.. | .. |
---|
15 | 12 | * TX queue 23 24 25 |
---|
16 | 13 | * RX-free queue 26 27 28 |
---|
17 | 14 | * TX-done queue is always 31, per-port RX and TX-ready queues are configurable |
---|
18 | | - * |
---|
19 | 15 | * |
---|
20 | 16 | * Queue entries: |
---|
21 | 17 | * bits 0 -> 1 - NPE ID (RX and TX-done) |
---|
.. | .. |
---|
31 | 27 | #include <linux/io.h> |
---|
32 | 28 | #include <linux/kernel.h> |
---|
33 | 29 | #include <linux/net_tstamp.h> |
---|
| 30 | +#include <linux/of.h> |
---|
34 | 31 | #include <linux/phy.h> |
---|
| 32 | +#include <linux/platform_data/eth_ixp4xx.h> |
---|
35 | 33 | #include <linux/platform_device.h> |
---|
36 | 34 | #include <linux/ptp_classify.h> |
---|
37 | 35 | #include <linux/slab.h> |
---|
38 | 36 | #include <linux/module.h> |
---|
39 | | -#include <mach/ixp46x_ts.h> |
---|
40 | | -#include <mach/npe.h> |
---|
41 | | -#include <mach/qmgr.h> |
---|
| 37 | +#include <linux/soc/ixp4xx/npe.h> |
---|
| 38 | +#include <linux/soc/ixp4xx/qmgr.h> |
---|
| 39 | + |
---|
| 40 | +#include "ixp46x_ts.h" |
---|
42 | 41 | |
---|
43 | 42 | #define DEBUG_DESC 0 |
---|
44 | 43 | #define DEBUG_RX 0 |
---|
.. | .. |
---|
139 | 138 | #ifdef __ARMEB__ |
---|
140 | 139 | typedef struct sk_buff buffer_t; |
---|
141 | 140 | #define free_buffer dev_kfree_skb |
---|
142 | | -#define free_buffer_irq dev_kfree_skb_irq |
---|
| 141 | +#define free_buffer_irq dev_consume_skb_irq |
---|
143 | 142 | #else |
---|
144 | 143 | typedef void buffer_t; |
---|
145 | 144 | #define free_buffer kfree |
---|
.. | .. |
---|
520 | 519 | return ret; |
---|
521 | 520 | } |
---|
522 | 521 | |
---|
523 | | -static int ixp4xx_mdio_register(void) |
---|
| 522 | +static int ixp4xx_mdio_register(struct eth_regs __iomem *regs) |
---|
524 | 523 | { |
---|
525 | 524 | int err; |
---|
526 | 525 | |
---|
527 | 526 | if (!(mdio_bus = mdiobus_alloc())) |
---|
528 | 527 | return -ENOMEM; |
---|
529 | 528 | |
---|
530 | | - if (cpu_is_ixp43x()) { |
---|
531 | | - /* IXP43x lacks NPE-B and uses NPE-C for MII PHY access */ |
---|
532 | | - if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEC_ETH)) |
---|
533 | | - return -ENODEV; |
---|
534 | | - mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthC_BASE_VIRT; |
---|
535 | | - } else { |
---|
536 | | - /* All MII PHY accesses use NPE-B Ethernet registers */ |
---|
537 | | - if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEB_ETH0)) |
---|
538 | | - return -ENODEV; |
---|
539 | | - mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT; |
---|
540 | | - } |
---|
541 | | - |
---|
| 529 | + mdio_regs = regs; |
---|
542 | 530 | __raw_writel(DEFAULT_CORE_CNTRL, &mdio_regs->core_control); |
---|
543 | 531 | spin_lock_init(&mdio_lock); |
---|
544 | 532 | mdio_bus->name = "IXP4xx MII Bus"; |
---|
.. | .. |
---|
584 | 572 | __raw_writel(DEFAULT_TX_CNTRL0 | TX_CNTRL0_HALFDUPLEX, |
---|
585 | 573 | &port->regs->tx_control[0]); |
---|
586 | 574 | |
---|
587 | | - printk(KERN_INFO "%s: link up, speed %u Mb/s, %s duplex\n", |
---|
588 | | - dev->name, port->speed, port->duplex ? "full" : "half"); |
---|
| 575 | + netdev_info(dev, "%s: link up, speed %u Mb/s, %s duplex\n", |
---|
| 576 | + dev->name, port->speed, port->duplex ? "full" : "half"); |
---|
589 | 577 | } |
---|
590 | 578 | |
---|
591 | 579 | |
---|
.. | .. |
---|
595 | 583 | #if DEBUG_PKT_BYTES |
---|
596 | 584 | int i; |
---|
597 | 585 | |
---|
598 | | - printk(KERN_DEBUG "%s: %s(%i) ", dev->name, func, len); |
---|
| 586 | + netdev_debug(dev, "%s(%i) ", func, len); |
---|
599 | 587 | for (i = 0; i < len; i++) { |
---|
600 | 588 | if (i >= DEBUG_PKT_BYTES) |
---|
601 | 589 | break; |
---|
.. | .. |
---|
686 | 674 | int received = 0; |
---|
687 | 675 | |
---|
688 | 676 | #if DEBUG_RX |
---|
689 | | - printk(KERN_DEBUG "%s: eth_poll\n", dev->name); |
---|
| 677 | + netdev_debug(dev, "eth_poll\n"); |
---|
690 | 678 | #endif |
---|
691 | 679 | |
---|
692 | 680 | while (received < budget) { |
---|
.. | .. |
---|
700 | 688 | |
---|
701 | 689 | if ((n = queue_get_desc(rxq, port, 0)) < 0) { |
---|
702 | 690 | #if DEBUG_RX |
---|
703 | | - printk(KERN_DEBUG "%s: eth_poll napi_complete\n", |
---|
704 | | - dev->name); |
---|
| 691 | + netdev_debug(dev, "eth_poll napi_complete\n"); |
---|
705 | 692 | #endif |
---|
706 | 693 | napi_complete(napi); |
---|
707 | 694 | qmgr_enable_irq(rxq); |
---|
708 | 695 | if (!qmgr_stat_below_low_watermark(rxq) && |
---|
709 | 696 | napi_reschedule(napi)) { /* not empty again */ |
---|
710 | 697 | #if DEBUG_RX |
---|
711 | | - printk(KERN_DEBUG "%s: eth_poll napi_reschedule succeeded\n", |
---|
712 | | - dev->name); |
---|
| 698 | + netdev_debug(dev, "eth_poll napi_reschedule succeeded\n"); |
---|
713 | 699 | #endif |
---|
714 | 700 | qmgr_disable_irq(rxq); |
---|
715 | 701 | continue; |
---|
716 | 702 | } |
---|
717 | 703 | #if DEBUG_RX |
---|
718 | | - printk(KERN_DEBUG "%s: eth_poll all done\n", |
---|
719 | | - dev->name); |
---|
| 704 | + netdev_debug(dev, "eth_poll all done\n"); |
---|
720 | 705 | #endif |
---|
721 | 706 | return received; /* all work done */ |
---|
722 | 707 | } |
---|
.. | .. |
---|
781 | 766 | } |
---|
782 | 767 | |
---|
783 | 768 | #if DEBUG_RX |
---|
784 | | - printk(KERN_DEBUG "eth_poll(): end, not all work done\n"); |
---|
| 769 | + netdev_debug(dev, "eth_poll(): end, not all work done\n"); |
---|
785 | 770 | #endif |
---|
786 | 771 | return received; /* not all work done */ |
---|
787 | 772 | } |
---|
.. | .. |
---|
845 | 830 | struct desc *desc; |
---|
846 | 831 | |
---|
847 | 832 | #if DEBUG_TX |
---|
848 | | - printk(KERN_DEBUG "%s: eth_xmit\n", dev->name); |
---|
| 833 | + netdev_debug(dev, "eth_xmit\n"); |
---|
849 | 834 | #endif |
---|
850 | 835 | |
---|
851 | 836 | if (unlikely(skb->len > MAX_MRU)) { |
---|
.. | .. |
---|
900 | 885 | |
---|
901 | 886 | if (qmgr_stat_below_low_watermark(txreadyq)) { /* empty */ |
---|
902 | 887 | #if DEBUG_TX |
---|
903 | | - printk(KERN_DEBUG "%s: eth_xmit queue full\n", dev->name); |
---|
| 888 | + netdev_debug(dev, "eth_xmit queue full\n"); |
---|
904 | 889 | #endif |
---|
905 | 890 | netif_stop_queue(dev); |
---|
906 | 891 | /* we could miss TX ready interrupt */ |
---|
907 | 892 | /* really empty in fact */ |
---|
908 | 893 | if (!qmgr_stat_below_low_watermark(txreadyq)) { |
---|
909 | 894 | #if DEBUG_TX |
---|
910 | | - printk(KERN_DEBUG "%s: eth_xmit ready again\n", |
---|
911 | | - dev->name); |
---|
| 895 | + netdev_debug(dev, "eth_xmit ready again\n"); |
---|
912 | 896 | #endif |
---|
913 | 897 | netif_wake_queue(dev); |
---|
914 | 898 | } |
---|
915 | 899 | } |
---|
916 | 900 | |
---|
917 | 901 | #if DEBUG_TX |
---|
918 | | - printk(KERN_DEBUG "%s: eth_xmit end\n", dev->name); |
---|
| 902 | + netdev_debug(dev, "eth_xmit end\n"); |
---|
919 | 903 | #endif |
---|
920 | 904 | |
---|
921 | 905 | ixp_tx_timestamp(port, skb); |
---|
.. | .. |
---|
1189 | 1173 | return err; |
---|
1190 | 1174 | |
---|
1191 | 1175 | if (npe_recv_message(npe, &msg, "ETH_GET_STATUS")) { |
---|
1192 | | - printk(KERN_ERR "%s: %s not responding\n", dev->name, |
---|
1193 | | - npe_name(npe)); |
---|
| 1176 | + netdev_err(dev, "%s not responding\n", npe_name(npe)); |
---|
1194 | 1177 | return -EIO; |
---|
1195 | 1178 | } |
---|
1196 | 1179 | port->firmware[0] = msg.byte4; |
---|
.. | .. |
---|
1302 | 1285 | msg.eth_id = port->id; |
---|
1303 | 1286 | msg.byte3 = 1; |
---|
1304 | 1287 | if (npe_send_recv_message(port->npe, &msg, "ETH_ENABLE_LOOPBACK")) |
---|
1305 | | - printk(KERN_CRIT "%s: unable to enable loopback\n", dev->name); |
---|
| 1288 | + netdev_crit(dev, "unable to enable loopback\n"); |
---|
1306 | 1289 | |
---|
1307 | 1290 | i = 0; |
---|
1308 | 1291 | do { /* drain RX buffers */ |
---|
.. | .. |
---|
1326 | 1309 | } while (++i < MAX_CLOSE_WAIT); |
---|
1327 | 1310 | |
---|
1328 | 1311 | if (buffs) |
---|
1329 | | - printk(KERN_CRIT "%s: unable to drain RX queue, %i buffer(s)" |
---|
1330 | | - " left in NPE\n", dev->name, buffs); |
---|
| 1312 | + netdev_crit(dev, "unable to drain RX queue, %i buffer(s)" |
---|
| 1313 | + " left in NPE\n", buffs); |
---|
1331 | 1314 | #if DEBUG_CLOSE |
---|
1332 | 1315 | if (!buffs) |
---|
1333 | | - printk(KERN_DEBUG "Draining RX queue took %i cycles\n", i); |
---|
| 1316 | + netdev_debug(dev, "draining RX queue took %i cycles\n", i); |
---|
1334 | 1317 | #endif |
---|
1335 | 1318 | |
---|
1336 | 1319 | buffs = TX_DESCS; |
---|
.. | .. |
---|
1346 | 1329 | } while (++i < MAX_CLOSE_WAIT); |
---|
1347 | 1330 | |
---|
1348 | 1331 | if (buffs) |
---|
1349 | | - printk(KERN_CRIT "%s: unable to drain TX queue, %i buffer(s) " |
---|
1350 | | - "left in NPE\n", dev->name, buffs); |
---|
| 1332 | + netdev_crit(dev, "unable to drain TX queue, %i buffer(s) " |
---|
| 1333 | + "left in NPE\n", buffs); |
---|
1351 | 1334 | #if DEBUG_CLOSE |
---|
1352 | 1335 | if (!buffs) |
---|
1353 | | - printk(KERN_DEBUG "Draining TX queues took %i cycles\n", i); |
---|
| 1336 | + netdev_debug(dev, "draining TX queues took %i cycles\n", i); |
---|
1354 | 1337 | #endif |
---|
1355 | 1338 | |
---|
1356 | 1339 | msg.byte3 = 0; |
---|
1357 | 1340 | if (npe_send_recv_message(port->npe, &msg, "ETH_DISABLE_LOOPBACK")) |
---|
1358 | | - printk(KERN_CRIT "%s: unable to disable loopback\n", |
---|
1359 | | - dev->name); |
---|
| 1341 | + netdev_crit(dev, "unable to disable loopback\n"); |
---|
1360 | 1342 | |
---|
1361 | 1343 | phy_stop(dev->phydev); |
---|
1362 | 1344 | |
---|
.. | .. |
---|
1377 | 1359 | .ndo_validate_addr = eth_validate_addr, |
---|
1378 | 1360 | }; |
---|
1379 | 1361 | |
---|
1380 | | -static int eth_init_one(struct platform_device *pdev) |
---|
| 1362 | +static int ixp4xx_eth_probe(struct platform_device *pdev) |
---|
1381 | 1363 | { |
---|
1382 | | - struct port *port; |
---|
1383 | | - struct net_device *dev; |
---|
1384 | | - struct eth_plat_info *plat = dev_get_platdata(&pdev->dev); |
---|
1385 | | - struct phy_device *phydev = NULL; |
---|
1386 | | - u32 regs_phys; |
---|
1387 | 1364 | char phy_id[MII_BUS_ID_SIZE + 3]; |
---|
| 1365 | + struct phy_device *phydev = NULL; |
---|
| 1366 | + struct device *dev = &pdev->dev; |
---|
| 1367 | + struct eth_plat_info *plat; |
---|
| 1368 | + resource_size_t regs_phys; |
---|
| 1369 | + struct net_device *ndev; |
---|
| 1370 | + struct resource *res; |
---|
| 1371 | + struct port *port; |
---|
1388 | 1372 | int err; |
---|
1389 | 1373 | |
---|
1390 | | - if (!(dev = alloc_etherdev(sizeof(struct port)))) |
---|
| 1374 | + plat = dev_get_platdata(dev); |
---|
| 1375 | + |
---|
| 1376 | + if (!(ndev = devm_alloc_etherdev(dev, sizeof(struct port)))) |
---|
1391 | 1377 | return -ENOMEM; |
---|
1392 | 1378 | |
---|
1393 | | - SET_NETDEV_DEV(dev, &pdev->dev); |
---|
1394 | | - port = netdev_priv(dev); |
---|
1395 | | - port->netdev = dev; |
---|
| 1379 | + SET_NETDEV_DEV(ndev, dev); |
---|
| 1380 | + port = netdev_priv(ndev); |
---|
| 1381 | + port->netdev = ndev; |
---|
1396 | 1382 | port->id = pdev->id; |
---|
| 1383 | + |
---|
| 1384 | + /* Get the port resource and remap */ |
---|
| 1385 | + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
| 1386 | + if (!res) |
---|
| 1387 | + return -ENODEV; |
---|
| 1388 | + regs_phys = res->start; |
---|
| 1389 | + port->regs = devm_ioremap_resource(dev, res); |
---|
| 1390 | + if (IS_ERR(port->regs)) |
---|
| 1391 | + return PTR_ERR(port->regs); |
---|
1397 | 1392 | |
---|
1398 | 1393 | switch (port->id) { |
---|
1399 | 1394 | case IXP4XX_ETH_NPEA: |
---|
1400 | | - port->regs = (struct eth_regs __iomem *)IXP4XX_EthA_BASE_VIRT; |
---|
1401 | | - regs_phys = IXP4XX_EthA_BASE_PHYS; |
---|
| 1395 | + /* If the MDIO bus is not up yet, defer probe */ |
---|
| 1396 | + if (!mdio_bus) |
---|
| 1397 | + return -EPROBE_DEFER; |
---|
1402 | 1398 | break; |
---|
1403 | 1399 | case IXP4XX_ETH_NPEB: |
---|
1404 | | - port->regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT; |
---|
1405 | | - regs_phys = IXP4XX_EthB_BASE_PHYS; |
---|
| 1400 | + /* |
---|
| 1401 | + * On all except IXP43x, NPE-B is used for the MDIO bus. |
---|
| 1402 | + * If there is no NPE-B in the feature set, bail out, else |
---|
| 1403 | + * register the MDIO bus. |
---|
| 1404 | + */ |
---|
| 1405 | + if (!cpu_is_ixp43x()) { |
---|
| 1406 | + if (!(ixp4xx_read_feature_bits() & |
---|
| 1407 | + IXP4XX_FEATURE_NPEB_ETH0)) |
---|
| 1408 | + return -ENODEV; |
---|
| 1409 | + /* Else register the MDIO bus on NPE-B */ |
---|
| 1410 | + if ((err = ixp4xx_mdio_register(port->regs))) |
---|
| 1411 | + return err; |
---|
| 1412 | + } |
---|
| 1413 | + if (!mdio_bus) |
---|
| 1414 | + return -EPROBE_DEFER; |
---|
1406 | 1415 | break; |
---|
1407 | 1416 | case IXP4XX_ETH_NPEC: |
---|
1408 | | - port->regs = (struct eth_regs __iomem *)IXP4XX_EthC_BASE_VIRT; |
---|
1409 | | - regs_phys = IXP4XX_EthC_BASE_PHYS; |
---|
| 1417 | + /* |
---|
| 1418 | + * IXP43x lacks NPE-B and uses NPE-C for the MDIO bus access, |
---|
| 1419 | + * of there is no NPE-C, no bus, nothing works, so bail out. |
---|
| 1420 | + */ |
---|
| 1421 | + if (cpu_is_ixp43x()) { |
---|
| 1422 | + if (!(ixp4xx_read_feature_bits() & |
---|
| 1423 | + IXP4XX_FEATURE_NPEC_ETH)) |
---|
| 1424 | + return -ENODEV; |
---|
| 1425 | + /* Else register the MDIO bus on NPE-C */ |
---|
| 1426 | + if ((err = ixp4xx_mdio_register(port->regs))) |
---|
| 1427 | + return err; |
---|
| 1428 | + } |
---|
| 1429 | + if (!mdio_bus) |
---|
| 1430 | + return -EPROBE_DEFER; |
---|
1410 | 1431 | break; |
---|
1411 | 1432 | default: |
---|
1412 | | - err = -ENODEV; |
---|
1413 | | - goto err_free; |
---|
| 1433 | + return -ENODEV; |
---|
1414 | 1434 | } |
---|
1415 | 1435 | |
---|
1416 | | - dev->netdev_ops = &ixp4xx_netdev_ops; |
---|
1417 | | - dev->ethtool_ops = &ixp4xx_ethtool_ops; |
---|
1418 | | - dev->tx_queue_len = 100; |
---|
| 1436 | + ndev->netdev_ops = &ixp4xx_netdev_ops; |
---|
| 1437 | + ndev->ethtool_ops = &ixp4xx_ethtool_ops; |
---|
| 1438 | + ndev->tx_queue_len = 100; |
---|
| 1439 | + /* Inherit the DMA masks from the platform device */ |
---|
| 1440 | + ndev->dev.dma_mask = dev->dma_mask; |
---|
| 1441 | + ndev->dev.coherent_dma_mask = dev->coherent_dma_mask; |
---|
1419 | 1442 | |
---|
1420 | | - netif_napi_add(dev, &port->napi, eth_poll, NAPI_WEIGHT); |
---|
| 1443 | + netif_napi_add(ndev, &port->napi, eth_poll, NAPI_WEIGHT); |
---|
1421 | 1444 | |
---|
1422 | | - if (!(port->npe = npe_request(NPE_ID(port->id)))) { |
---|
1423 | | - err = -EIO; |
---|
1424 | | - goto err_free; |
---|
1425 | | - } |
---|
| 1445 | + if (!(port->npe = npe_request(NPE_ID(port->id)))) |
---|
| 1446 | + return -EIO; |
---|
1426 | 1447 | |
---|
1427 | | - port->mem_res = request_mem_region(regs_phys, REGS_SIZE, dev->name); |
---|
| 1448 | + port->mem_res = request_mem_region(regs_phys, REGS_SIZE, ndev->name); |
---|
1428 | 1449 | if (!port->mem_res) { |
---|
1429 | 1450 | err = -EBUSY; |
---|
1430 | 1451 | goto err_npe_rel; |
---|
.. | .. |
---|
1432 | 1453 | |
---|
1433 | 1454 | port->plat = plat; |
---|
1434 | 1455 | npe_port_tab[NPE_ID(port->id)] = port; |
---|
1435 | | - memcpy(dev->dev_addr, plat->hwaddr, ETH_ALEN); |
---|
| 1456 | + memcpy(ndev->dev_addr, plat->hwaddr, ETH_ALEN); |
---|
1436 | 1457 | |
---|
1437 | | - platform_set_drvdata(pdev, dev); |
---|
| 1458 | + platform_set_drvdata(pdev, ndev); |
---|
1438 | 1459 | |
---|
1439 | 1460 | __raw_writel(DEFAULT_CORE_CNTRL | CORE_RESET, |
---|
1440 | 1461 | &port->regs->core_control); |
---|
.. | .. |
---|
1444 | 1465 | |
---|
1445 | 1466 | snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, |
---|
1446 | 1467 | mdio_bus->id, plat->phy); |
---|
1447 | | - phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, |
---|
| 1468 | + phydev = phy_connect(ndev, phy_id, &ixp4xx_adjust_link, |
---|
1448 | 1469 | PHY_INTERFACE_MODE_MII); |
---|
1449 | 1470 | if (IS_ERR(phydev)) { |
---|
1450 | 1471 | err = PTR_ERR(phydev); |
---|
.. | .. |
---|
1453 | 1474 | |
---|
1454 | 1475 | phydev->irq = PHY_POLL; |
---|
1455 | 1476 | |
---|
1456 | | - if ((err = register_netdev(dev))) |
---|
| 1477 | + if ((err = register_netdev(ndev))) |
---|
1457 | 1478 | goto err_phy_dis; |
---|
1458 | 1479 | |
---|
1459 | | - printk(KERN_INFO "%s: MII PHY %i on %s\n", dev->name, plat->phy, |
---|
1460 | | - npe_name(port->npe)); |
---|
| 1480 | + netdev_info(ndev, "%s: MII PHY %i on %s\n", ndev->name, plat->phy, |
---|
| 1481 | + npe_name(port->npe)); |
---|
1461 | 1482 | |
---|
1462 | 1483 | return 0; |
---|
1463 | 1484 | |
---|
.. | .. |
---|
1468 | 1489 | release_resource(port->mem_res); |
---|
1469 | 1490 | err_npe_rel: |
---|
1470 | 1491 | npe_release(port->npe); |
---|
1471 | | -err_free: |
---|
1472 | | - free_netdev(dev); |
---|
1473 | 1492 | return err; |
---|
1474 | 1493 | } |
---|
1475 | 1494 | |
---|
1476 | | -static int eth_remove_one(struct platform_device *pdev) |
---|
| 1495 | +static int ixp4xx_eth_remove(struct platform_device *pdev) |
---|
1477 | 1496 | { |
---|
1478 | | - struct net_device *dev = platform_get_drvdata(pdev); |
---|
1479 | | - struct phy_device *phydev = dev->phydev; |
---|
1480 | | - struct port *port = netdev_priv(dev); |
---|
| 1497 | + struct net_device *ndev = platform_get_drvdata(pdev); |
---|
| 1498 | + struct phy_device *phydev = ndev->phydev; |
---|
| 1499 | + struct port *port = netdev_priv(ndev); |
---|
1481 | 1500 | |
---|
1482 | | - unregister_netdev(dev); |
---|
| 1501 | + unregister_netdev(ndev); |
---|
1483 | 1502 | phy_disconnect(phydev); |
---|
| 1503 | + ixp4xx_mdio_remove(); |
---|
1484 | 1504 | npe_port_tab[NPE_ID(port->id)] = NULL; |
---|
1485 | 1505 | npe_release(port->npe); |
---|
1486 | 1506 | release_resource(port->mem_res); |
---|
1487 | | - free_netdev(dev); |
---|
1488 | 1507 | return 0; |
---|
1489 | 1508 | } |
---|
1490 | 1509 | |
---|
1491 | 1510 | static struct platform_driver ixp4xx_eth_driver = { |
---|
1492 | 1511 | .driver.name = DRV_NAME, |
---|
1493 | | - .probe = eth_init_one, |
---|
1494 | | - .remove = eth_remove_one, |
---|
| 1512 | + .probe = ixp4xx_eth_probe, |
---|
| 1513 | + .remove = ixp4xx_eth_remove, |
---|
1495 | 1514 | }; |
---|
1496 | | - |
---|
1497 | | -static int __init eth_init_module(void) |
---|
1498 | | -{ |
---|
1499 | | - int err; |
---|
1500 | | - if ((err = ixp4xx_mdio_register())) |
---|
1501 | | - return err; |
---|
1502 | | - return platform_driver_register(&ixp4xx_eth_driver); |
---|
1503 | | -} |
---|
1504 | | - |
---|
1505 | | -static void __exit eth_cleanup_module(void) |
---|
1506 | | -{ |
---|
1507 | | - platform_driver_unregister(&ixp4xx_eth_driver); |
---|
1508 | | - ixp4xx_mdio_remove(); |
---|
1509 | | -} |
---|
| 1515 | +module_platform_driver(ixp4xx_eth_driver); |
---|
1510 | 1516 | |
---|
1511 | 1517 | MODULE_AUTHOR("Krzysztof Halasa"); |
---|
1512 | 1518 | MODULE_DESCRIPTION("Intel IXP4xx Ethernet driver"); |
---|
1513 | 1519 | MODULE_LICENSE("GPL v2"); |
---|
1514 | 1520 | MODULE_ALIAS("platform:ixp4xx_eth"); |
---|
1515 | | -module_init(eth_init_module); |
---|
1516 | | -module_exit(eth_cleanup_module); |
---|