diff options
author | David Daney <david.daney@cavium.com> | 2012-07-05 12:12:40 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2012-07-23 08:54:53 -0400 |
commit | df9244c5365c12d0cd1452323d3dc3ef91d80173 (patch) | |
tree | 8dafc6533b6fbcf334e556e771c112c7751dd46c /drivers/staging | |
parent | 368bec0d4a84f78f8c2be8441916d905a8da73c2 (diff) |
staging: octeon_ethernet: Convert to use device tree.
Get MAC address and PHY connection from the device tree. The driver
is converted to a platform driver.
Signed-off-by: David Daney <david.daney@cavium.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Cc: linux-mips@linux-mips.org
Cc: devicetree-discuss@lists.ozlabs.org
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/3940/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/octeon/ethernet-mdio.c | 28 | ||||
-rw-r--r-- | drivers/staging/octeon/ethernet.c | 153 | ||||
-rw-r--r-- | drivers/staging/octeon/octeon-ethernet.h | 3 |
3 files changed, 117 insertions, 67 deletions
diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c index e31949c9c87e..f15b31b37ca5 100644 --- a/drivers/staging/octeon/ethernet-mdio.c +++ b/drivers/staging/octeon/ethernet-mdio.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/ethtool.h> | 28 | #include <linux/ethtool.h> |
29 | #include <linux/phy.h> | 29 | #include <linux/phy.h> |
30 | #include <linux/ratelimit.h> | 30 | #include <linux/ratelimit.h> |
31 | #include <linux/of_mdio.h> | ||
31 | 32 | ||
32 | #include <net/dst.h> | 33 | #include <net/dst.h> |
33 | 34 | ||
@@ -161,22 +162,23 @@ static void cvm_oct_adjust_link(struct net_device *dev) | |||
161 | int cvm_oct_phy_setup_device(struct net_device *dev) | 162 | int cvm_oct_phy_setup_device(struct net_device *dev) |
162 | { | 163 | { |
163 | struct octeon_ethernet *priv = netdev_priv(dev); | 164 | struct octeon_ethernet *priv = netdev_priv(dev); |
165 | struct device_node *phy_node; | ||
164 | 166 | ||
165 | int phy_addr = cvmx_helper_board_get_mii_address(priv->port); | 167 | if (!priv->of_node) |
166 | if (phy_addr != -1) { | 168 | return 0; |
167 | char phy_id[MII_BUS_ID_SIZE + 3]; | ||
168 | 169 | ||
169 | snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, "mdio-octeon-0", phy_addr); | 170 | phy_node = of_parse_phandle(priv->of_node, "phy-handle", 0); |
171 | if (!phy_node) | ||
172 | return 0; | ||
170 | 173 | ||
171 | priv->phydev = phy_connect(dev, phy_id, cvm_oct_adjust_link, 0, | 174 | priv->phydev = of_phy_connect(dev, phy_node, cvm_oct_adjust_link, 0, |
172 | PHY_INTERFACE_MODE_GMII); | 175 | PHY_INTERFACE_MODE_GMII); |
176 | |||
177 | if (priv->phydev == NULL) | ||
178 | return -ENODEV; | ||
179 | |||
180 | priv->last_link = 0; | ||
181 | phy_start_aneg(priv->phydev); | ||
173 | 182 | ||
174 | if (IS_ERR(priv->phydev)) { | ||
175 | priv->phydev = NULL; | ||
176 | return -1; | ||
177 | } | ||
178 | priv->last_link = 0; | ||
179 | phy_start_aneg(priv->phydev); | ||
180 | } | ||
181 | return 0; | 183 | return 0; |
182 | } | 184 | } |
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index 18f7a790f73d..683bedc74dde 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c | |||
@@ -24,6 +24,7 @@ | |||
24 | * This file may also be available under a different license from Cavium. | 24 | * This file may also be available under a different license from Cavium. |
25 | * Contact Cavium Networks for more information | 25 | * Contact Cavium Networks for more information |
26 | **********************************************************************/ | 26 | **********************************************************************/ |
27 | #include <linux/platform_device.h> | ||
27 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
28 | #include <linux/init.h> | 29 | #include <linux/init.h> |
29 | #include <linux/module.h> | 30 | #include <linux/module.h> |
@@ -32,6 +33,7 @@ | |||
32 | #include <linux/phy.h> | 33 | #include <linux/phy.h> |
33 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
34 | #include <linux/interrupt.h> | 35 | #include <linux/interrupt.h> |
36 | #include <linux/of_net.h> | ||
35 | 37 | ||
36 | #include <net/dst.h> | 38 | #include <net/dst.h> |
37 | 39 | ||
@@ -113,15 +115,6 @@ int rx_napi_weight = 32; | |||
113 | module_param(rx_napi_weight, int, 0444); | 115 | module_param(rx_napi_weight, int, 0444); |
114 | MODULE_PARM_DESC(rx_napi_weight, "The NAPI WEIGHT parameter."); | 116 | MODULE_PARM_DESC(rx_napi_weight, "The NAPI WEIGHT parameter."); |
115 | 117 | ||
116 | /* | ||
117 | * The offset from mac_addr_base that should be used for the next port | ||
118 | * that is configured. By convention, if any mgmt ports exist on the | ||
119 | * chip, they get the first mac addresses, The ports controlled by | ||
120 | * this driver are numbered sequencially following any mgmt addresses | ||
121 | * that may exist. | ||
122 | */ | ||
123 | static unsigned int cvm_oct_mac_addr_offset; | ||
124 | |||
125 | /** | 118 | /** |
126 | * cvm_oct_poll_queue - Workqueue for polling operations. | 119 | * cvm_oct_poll_queue - Workqueue for polling operations. |
127 | */ | 120 | */ |
@@ -176,7 +169,7 @@ static void cvm_oct_periodic_worker(struct work_struct *work) | |||
176 | queue_delayed_work(cvm_oct_poll_queue, &priv->port_periodic_work, HZ); | 169 | queue_delayed_work(cvm_oct_poll_queue, &priv->port_periodic_work, HZ); |
177 | } | 170 | } |
178 | 171 | ||
179 | static __init void cvm_oct_configure_common_hw(void) | 172 | static __devinit void cvm_oct_configure_common_hw(void) |
180 | { | 173 | { |
181 | /* Setup the FPA */ | 174 | /* Setup the FPA */ |
182 | cvmx_fpa_enable(); | 175 | cvmx_fpa_enable(); |
@@ -396,23 +389,21 @@ static void cvm_oct_common_set_multicast_list(struct net_device *dev) | |||
396 | 389 | ||
397 | * Returns Zero on success | 390 | * Returns Zero on success |
398 | */ | 391 | */ |
399 | static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr) | 392 | static int cvm_oct_set_mac_filter(struct net_device *dev) |
400 | { | 393 | { |
401 | struct octeon_ethernet *priv = netdev_priv(dev); | 394 | struct octeon_ethernet *priv = netdev_priv(dev); |
402 | union cvmx_gmxx_prtx_cfg gmx_cfg; | 395 | union cvmx_gmxx_prtx_cfg gmx_cfg; |
403 | int interface = INTERFACE(priv->port); | 396 | int interface = INTERFACE(priv->port); |
404 | int index = INDEX(priv->port); | 397 | int index = INDEX(priv->port); |
405 | 398 | ||
406 | memcpy(dev->dev_addr, addr + 2, 6); | ||
407 | |||
408 | if ((interface < 2) | 399 | if ((interface < 2) |
409 | && (cvmx_helper_interface_get_mode(interface) != | 400 | && (cvmx_helper_interface_get_mode(interface) != |
410 | CVMX_HELPER_INTERFACE_MODE_SPI)) { | 401 | CVMX_HELPER_INTERFACE_MODE_SPI)) { |
411 | int i; | 402 | int i; |
412 | uint8_t *ptr = addr; | 403 | uint8_t *ptr = dev->dev_addr; |
413 | uint64_t mac = 0; | 404 | uint64_t mac = 0; |
414 | for (i = 0; i < 6; i++) | 405 | for (i = 0; i < 6; i++) |
415 | mac = (mac << 8) | (uint64_t) (ptr[i + 2]); | 406 | mac = (mac << 8) | (uint64_t)ptr[i]; |
416 | 407 | ||
417 | gmx_cfg.u64 = | 408 | gmx_cfg.u64 = |
418 | cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); | 409 | cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); |
@@ -421,17 +412,17 @@ static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr) | |||
421 | 412 | ||
422 | cvmx_write_csr(CVMX_GMXX_SMACX(index, interface), mac); | 413 | cvmx_write_csr(CVMX_GMXX_SMACX(index, interface), mac); |
423 | cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM0(index, interface), | 414 | cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM0(index, interface), |
424 | ptr[2]); | 415 | ptr[0]); |
425 | cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM1(index, interface), | 416 | cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM1(index, interface), |
426 | ptr[3]); | 417 | ptr[1]); |
427 | cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM2(index, interface), | 418 | cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM2(index, interface), |
428 | ptr[4]); | 419 | ptr[2]); |
429 | cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM3(index, interface), | 420 | cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM3(index, interface), |
430 | ptr[5]); | 421 | ptr[3]); |
431 | cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM4(index, interface), | 422 | cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM4(index, interface), |
432 | ptr[6]); | 423 | ptr[4]); |
433 | cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM5(index, interface), | 424 | cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM5(index, interface), |
434 | ptr[7]); | 425 | ptr[5]); |
435 | cvm_oct_common_set_multicast_list(dev); | 426 | cvm_oct_common_set_multicast_list(dev); |
436 | cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), | 427 | cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), |
437 | gmx_cfg.u64); | 428 | gmx_cfg.u64); |
@@ -439,6 +430,15 @@ static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr) | |||
439 | return 0; | 430 | return 0; |
440 | } | 431 | } |
441 | 432 | ||
433 | static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr) | ||
434 | { | ||
435 | int r = eth_mac_addr(dev, addr); | ||
436 | |||
437 | if (r) | ||
438 | return r; | ||
439 | return cvm_oct_set_mac_filter(dev); | ||
440 | } | ||
441 | |||
442 | /** | 442 | /** |
443 | * cvm_oct_common_init - per network device initialization | 443 | * cvm_oct_common_init - per network device initialization |
444 | * @dev: Device to initialize | 444 | * @dev: Device to initialize |
@@ -448,26 +448,17 @@ static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr) | |||
448 | int cvm_oct_common_init(struct net_device *dev) | 448 | int cvm_oct_common_init(struct net_device *dev) |
449 | { | 449 | { |
450 | struct octeon_ethernet *priv = netdev_priv(dev); | 450 | struct octeon_ethernet *priv = netdev_priv(dev); |
451 | struct sockaddr sa; | 451 | const u8 *mac = NULL; |
452 | u64 mac = ((u64)(octeon_bootinfo->mac_addr_base[0] & 0xff) << 40) | | 452 | |
453 | ((u64)(octeon_bootinfo->mac_addr_base[1] & 0xff) << 32) | | 453 | if (priv->of_node) |
454 | ((u64)(octeon_bootinfo->mac_addr_base[2] & 0xff) << 24) | | 454 | mac = of_get_mac_address(priv->of_node); |
455 | ((u64)(octeon_bootinfo->mac_addr_base[3] & 0xff) << 16) | | 455 | |
456 | ((u64)(octeon_bootinfo->mac_addr_base[4] & 0xff) << 8) | | 456 | if (mac && is_valid_ether_addr(mac)) { |
457 | (u64)(octeon_bootinfo->mac_addr_base[5] & 0xff); | 457 | memcpy(dev->dev_addr, mac, ETH_ALEN); |
458 | 458 | dev->addr_assign_type &= ~NET_ADDR_RANDOM; | |
459 | mac += cvm_oct_mac_addr_offset; | 459 | } else { |
460 | sa.sa_data[0] = (mac >> 40) & 0xff; | 460 | eth_hw_addr_random(dev); |
461 | sa.sa_data[1] = (mac >> 32) & 0xff; | 461 | } |
462 | sa.sa_data[2] = (mac >> 24) & 0xff; | ||
463 | sa.sa_data[3] = (mac >> 16) & 0xff; | ||
464 | sa.sa_data[4] = (mac >> 8) & 0xff; | ||
465 | sa.sa_data[5] = mac & 0xff; | ||
466 | |||
467 | if (cvm_oct_mac_addr_offset >= octeon_bootinfo->mac_addr_count) | ||
468 | printk(KERN_DEBUG "%s: Using MAC outside of the assigned range:" | ||
469 | " %pM\n", dev->name, sa.sa_data); | ||
470 | cvm_oct_mac_addr_offset++; | ||
471 | 462 | ||
472 | /* | 463 | /* |
473 | * Force the interface to use the POW send if always_use_pow | 464 | * Force the interface to use the POW send if always_use_pow |
@@ -488,7 +479,7 @@ int cvm_oct_common_init(struct net_device *dev) | |||
488 | SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops); | 479 | SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops); |
489 | 480 | ||
490 | cvm_oct_phy_setup_device(dev); | 481 | cvm_oct_phy_setup_device(dev); |
491 | dev->netdev_ops->ndo_set_mac_address(dev, &sa); | 482 | cvm_oct_set_mac_filter(dev); |
492 | dev->netdev_ops->ndo_change_mtu(dev, dev->mtu); | 483 | dev->netdev_ops->ndo_change_mtu(dev, dev->mtu); |
493 | 484 | ||
494 | /* | 485 | /* |
@@ -595,22 +586,55 @@ static const struct net_device_ops cvm_oct_pow_netdev_ops = { | |||
595 | 586 | ||
596 | extern void octeon_mdiobus_force_mod_depencency(void); | 587 | extern void octeon_mdiobus_force_mod_depencency(void); |
597 | 588 | ||
598 | static int __init cvm_oct_init_module(void) | 589 | static struct device_node * __devinit cvm_oct_of_get_child(const struct device_node *parent, |
590 | int reg_val) | ||
591 | { | ||
592 | struct device_node *node = NULL; | ||
593 | int size; | ||
594 | const __be32 *addr; | ||
595 | |||
596 | for (;;) { | ||
597 | node = of_get_next_child(parent, node); | ||
598 | if (!node) | ||
599 | break; | ||
600 | addr = of_get_property(node, "reg", &size); | ||
601 | if (addr && (be32_to_cpu(*addr) == reg_val)) | ||
602 | break; | ||
603 | } | ||
604 | return node; | ||
605 | } | ||
606 | |||
607 | static struct device_node * __devinit cvm_oct_node_for_port(struct device_node *pip, | ||
608 | int interface, int port) | ||
609 | { | ||
610 | struct device_node *ni, *np; | ||
611 | |||
612 | ni = cvm_oct_of_get_child(pip, interface); | ||
613 | if (!ni) | ||
614 | return NULL; | ||
615 | |||
616 | np = cvm_oct_of_get_child(ni, port); | ||
617 | of_node_put(ni); | ||
618 | |||
619 | return np; | ||
620 | } | ||
621 | |||
622 | static int __devinit cvm_oct_probe(struct platform_device *pdev) | ||
599 | { | 623 | { |
600 | int num_interfaces; | 624 | int num_interfaces; |
601 | int interface; | 625 | int interface; |
602 | int fau = FAU_NUM_PACKET_BUFFERS_TO_FREE; | 626 | int fau = FAU_NUM_PACKET_BUFFERS_TO_FREE; |
603 | int qos; | 627 | int qos; |
628 | struct device_node *pip; | ||
604 | 629 | ||
605 | octeon_mdiobus_force_mod_depencency(); | 630 | octeon_mdiobus_force_mod_depencency(); |
606 | pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION); | 631 | pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION); |
607 | 632 | ||
608 | if (OCTEON_IS_MODEL(OCTEON_CN52XX)) | 633 | pip = pdev->dev.of_node; |
609 | cvm_oct_mac_addr_offset = 2; /* First two are the mgmt ports. */ | 634 | if (!pip) { |
610 | else if (OCTEON_IS_MODEL(OCTEON_CN56XX)) | 635 | pr_err("Error: No 'pip' in /aliases\n"); |
611 | cvm_oct_mac_addr_offset = 1; /* First one is the mgmt port. */ | 636 | return -EINVAL; |
612 | else | 637 | } |
613 | cvm_oct_mac_addr_offset = 0; | ||
614 | 638 | ||
615 | cvm_oct_poll_queue = create_singlethread_workqueue("octeon-ethernet"); | 639 | cvm_oct_poll_queue = create_singlethread_workqueue("octeon-ethernet"); |
616 | if (cvm_oct_poll_queue == NULL) { | 640 | if (cvm_oct_poll_queue == NULL) { |
@@ -689,10 +713,11 @@ static int __init cvm_oct_init_module(void) | |||
689 | cvmx_helper_interface_get_mode(interface); | 713 | cvmx_helper_interface_get_mode(interface); |
690 | int num_ports = cvmx_helper_ports_on_interface(interface); | 714 | int num_ports = cvmx_helper_ports_on_interface(interface); |
691 | int port; | 715 | int port; |
716 | int port_index; | ||
692 | 717 | ||
693 | for (port = cvmx_helper_get_ipd_port(interface, 0); | 718 | for (port_index = 0, port = cvmx_helper_get_ipd_port(interface, 0); |
694 | port < cvmx_helper_get_ipd_port(interface, num_ports); | 719 | port < cvmx_helper_get_ipd_port(interface, num_ports); |
695 | port++) { | 720 | port_index++, port++) { |
696 | struct octeon_ethernet *priv; | 721 | struct octeon_ethernet *priv; |
697 | struct net_device *dev = | 722 | struct net_device *dev = |
698 | alloc_etherdev(sizeof(struct octeon_ethernet)); | 723 | alloc_etherdev(sizeof(struct octeon_ethernet)); |
@@ -703,6 +728,7 @@ static int __init cvm_oct_init_module(void) | |||
703 | 728 | ||
704 | /* Initialize the device private structure. */ | 729 | /* Initialize the device private structure. */ |
705 | priv = netdev_priv(dev); | 730 | priv = netdev_priv(dev); |
731 | priv->of_node = cvm_oct_node_for_port(pip, interface, port_index); | ||
706 | 732 | ||
707 | INIT_DELAYED_WORK(&priv->port_periodic_work, | 733 | INIT_DELAYED_WORK(&priv->port_periodic_work, |
708 | cvm_oct_periodic_worker); | 734 | cvm_oct_periodic_worker); |
@@ -787,7 +813,7 @@ static int __init cvm_oct_init_module(void) | |||
787 | return 0; | 813 | return 0; |
788 | } | 814 | } |
789 | 815 | ||
790 | static void __exit cvm_oct_cleanup_module(void) | 816 | static int __devexit cvm_oct_remove(struct platform_device *pdev) |
791 | { | 817 | { |
792 | int port; | 818 | int port; |
793 | 819 | ||
@@ -835,10 +861,29 @@ static void __exit cvm_oct_cleanup_module(void) | |||
835 | if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL) | 861 | if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL) |
836 | cvm_oct_mem_empty_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL, | 862 | cvm_oct_mem_empty_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL, |
837 | CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128); | 863 | CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128); |
864 | return 0; | ||
838 | } | 865 | } |
839 | 866 | ||
867 | static struct of_device_id cvm_oct_match[] = { | ||
868 | { | ||
869 | .compatible = "cavium,octeon-3860-pip", | ||
870 | }, | ||
871 | {}, | ||
872 | }; | ||
873 | MODULE_DEVICE_TABLE(of, cvm_oct_match); | ||
874 | |||
875 | static struct platform_driver cvm_oct_driver = { | ||
876 | .probe = cvm_oct_probe, | ||
877 | .remove = __devexit_p(cvm_oct_remove), | ||
878 | .driver = { | ||
879 | .owner = THIS_MODULE, | ||
880 | .name = KBUILD_MODNAME, | ||
881 | .of_match_table = cvm_oct_match, | ||
882 | }, | ||
883 | }; | ||
884 | |||
885 | module_platform_driver(cvm_oct_driver); | ||
886 | |||
840 | MODULE_LICENSE("GPL"); | 887 | MODULE_LICENSE("GPL"); |
841 | MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>"); | 888 | MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>"); |
842 | MODULE_DESCRIPTION("Cavium Networks Octeon ethernet driver."); | 889 | MODULE_DESCRIPTION("Cavium Networks Octeon ethernet driver."); |
843 | module_init(cvm_oct_init_module); | ||
844 | module_exit(cvm_oct_cleanup_module); | ||
diff --git a/drivers/staging/octeon/octeon-ethernet.h b/drivers/staging/octeon/octeon-ethernet.h index d58192563552..9360e22e0739 100644 --- a/drivers/staging/octeon/octeon-ethernet.h +++ b/drivers/staging/octeon/octeon-ethernet.h | |||
@@ -31,6 +31,8 @@ | |||
31 | #ifndef OCTEON_ETHERNET_H | 31 | #ifndef OCTEON_ETHERNET_H |
32 | #define OCTEON_ETHERNET_H | 32 | #define OCTEON_ETHERNET_H |
33 | 33 | ||
34 | #include <linux/of.h> | ||
35 | |||
34 | /** | 36 | /** |
35 | * This is the definition of the Ethernet driver's private | 37 | * This is the definition of the Ethernet driver's private |
36 | * driver state stored in netdev_priv(dev). | 38 | * driver state stored in netdev_priv(dev). |
@@ -59,6 +61,7 @@ struct octeon_ethernet { | |||
59 | void (*poll) (struct net_device *dev); | 61 | void (*poll) (struct net_device *dev); |
60 | struct delayed_work port_periodic_work; | 62 | struct delayed_work port_periodic_work; |
61 | struct work_struct port_work; /* may be unused. */ | 63 | struct work_struct port_work; /* may be unused. */ |
64 | struct device_node *of_node; | ||
62 | }; | 65 | }; |
63 | 66 | ||
64 | int cvm_oct_free_work(void *work_queue_entry); | 67 | int cvm_oct_free_work(void *work_queue_entry); |