Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: pcs: xpcs: Add fwnode-based descriptor creation method

It's now possible to have the DW XPCS device defined as a standard
platform device for instance in the platform DT-file. Although that
functionality is useless unless there is a way to have the device found by
the client drivers (STMMAC/DW *MAC, NXP SJA1105 Eth Switch, etc). Provide
such ability by means of the xpcs_create_fwnode() method. It needs to be
called with the device DW XPCS fwnode instance passed. That node will be
then used to find the MDIO-device instance in order to create the DW XPCS
descriptor.

Note the method semantics and name is similar to what has been recently
introduced in the Lynx PCS driver.

Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Serge Semin and committed by
David S. Miller
9cad7275 f6bb3e9d

+53
+50
drivers/net/pcs/pcs-xpcs.c
··· 10 10 #include <linux/delay.h> 11 11 #include <linux/pcs/pcs-xpcs.h> 12 12 #include <linux/mdio.h> 13 + #include <linux/phy.h> 13 14 #include <linux/phylink.h> 15 + #include <linux/property.h> 14 16 15 17 #include "pcs-xpcs.h" 16 18 ··· 1507 1505 return ERR_PTR(ret); 1508 1506 } 1509 1507 1508 + /** 1509 + * xpcs_create_mdiodev() - create a DW xPCS instance with the MDIO @addr 1510 + * @bus: pointer to the MDIO-bus descriptor for the device to be looked at 1511 + * @addr: device MDIO-bus ID 1512 + * @interface: requested PHY interface 1513 + * 1514 + * Return: a pointer to the DW XPCS handle if successful, otherwise -ENODEV if 1515 + * the PCS device couldn't be found on the bus and other negative errno related 1516 + * to the data allocation and MDIO-bus communications. 1517 + */ 1510 1518 struct dw_xpcs *xpcs_create_mdiodev(struct mii_bus *bus, int addr, 1511 1519 phy_interface_t interface) 1512 1520 { ··· 1540 1528 return xpcs; 1541 1529 } 1542 1530 EXPORT_SYMBOL_GPL(xpcs_create_mdiodev); 1531 + 1532 + /** 1533 + * xpcs_create_fwnode() - Create a DW xPCS instance from @fwnode 1534 + * @fwnode: fwnode handle poining to the DW XPCS device 1535 + * @interface: requested PHY interface 1536 + * 1537 + * Return: a pointer to the DW XPCS handle if successful, otherwise -ENODEV if 1538 + * the fwnode device is unavailable or the PCS device couldn't be found on the 1539 + * bus, -EPROBE_DEFER if the respective MDIO-device instance couldn't be found, 1540 + * other negative errno related to the data allocations and MDIO-bus 1541 + * communications. 1542 + */ 1543 + struct dw_xpcs *xpcs_create_fwnode(struct fwnode_handle *fwnode, 1544 + phy_interface_t interface) 1545 + { 1546 + struct mdio_device *mdiodev; 1547 + struct dw_xpcs *xpcs; 1548 + 1549 + if (!fwnode_device_is_available(fwnode)) 1550 + return ERR_PTR(-ENODEV); 1551 + 1552 + mdiodev = fwnode_mdio_find_device(fwnode); 1553 + if (!mdiodev) 1554 + return ERR_PTR(-EPROBE_DEFER); 1555 + 1556 + xpcs = xpcs_create(mdiodev, interface); 1557 + 1558 + /* xpcs_create() has taken a refcount on the mdiodev if it was 1559 + * successful. If xpcs_create() fails, this will free the mdio 1560 + * device here. In any case, we don't need to hold our reference 1561 + * anymore, and putting it here will allow mdio_device_put() in 1562 + * xpcs_destroy() to automatically free the mdio device. 1563 + */ 1564 + mdio_device_put(mdiodev); 1565 + 1566 + return xpcs; 1567 + } 1568 + EXPORT_SYMBOL_GPL(xpcs_create_fwnode); 1543 1569 1544 1570 void xpcs_destroy(struct dw_xpcs *xpcs) 1545 1571 {
+3
include/linux/pcs/pcs-xpcs.h
··· 8 8 #define __LINUX_PCS_XPCS_H 9 9 10 10 #include <linux/clk.h> 11 + #include <linux/fwnode.h> 11 12 #include <linux/mdio.h> 12 13 #include <linux/phy.h> 13 14 #include <linux/phylink.h> ··· 73 72 int enable); 74 73 struct dw_xpcs *xpcs_create_mdiodev(struct mii_bus *bus, int addr, 75 74 phy_interface_t interface); 75 + struct dw_xpcs *xpcs_create_fwnode(struct fwnode_handle *fwnode, 76 + phy_interface_t interface); 76 77 void xpcs_destroy(struct dw_xpcs *xpcs); 77 78 78 79 #endif /* __LINUX_PCS_XPCS_H */