Skip to content

Commit 68bd67b

Browse files
committed
Merge branch 'complete-lynx-mdio-device-handling'
Russell King says: ==================== complete Lynx mdio device handling This series completes the mdio device lifetime handling for Lynx PCS users which do not create their own mdio device, but instead fetch it using a firmware description - namely the DPAA2 and FMAN_MEMAC drivers. In a previous patch set, lynx_pcs_create() was modified to increase the mdio device refcount, and lynx_pcs_destroy() to drop that refcount. The first two patches change these two drivers to put the reference which they hold immediately after lynx_pcs_create(), effectively handing the responsibility for maintaining the refcount to the Lynx PCS driver. A side effect of the first two patches is that lynx_get_mdio_device() is no longer used, so patch 3 removes it. Patch 4 adds a new helper - lynx_pcs_create_fwnode(), which creates a Lynx PCS instance from the fwnode. Patch 5 and 6 convert the two drivers to make use of this new helper, which simply has to find the mdio device, and then create the Lynx PCS from that. With those conversions done, lynx_pcs_create() is no longer required outside pcs-lynx.c, so remove it from public view. Patch 8 we changes lynx_pcs_create() to return an error-pointer rather than NULL to bring consistency to the return style, and means that we can remove the NULL-to-error-pointer conversion from both lynx_pcs_create_fwnode() and lynx_pcs_create_mdiodev(). Patch 9 adds a check for the fwnode being available, and returns an -ENODEV error pointer if unavailable. Patch 10 removes this check from DPAA2, detecting the error pointer value to continue printing the helpful message. Patch 11 removes this check from fman_memac, and in doing so fixes a bug where if the node is unavailable, the reference count is not dropped. ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents c8cc2ae + 32fc303 commit 68bd67b

File tree

4 files changed

+58
-50
lines changed

4 files changed

+58
-50
lines changed

drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,8 @@ static int dpaa2_pcs_create(struct dpaa2_mac *mac,
247247
struct fwnode_handle *dpmac_node,
248248
int id)
249249
{
250-
struct mdio_device *mdiodev;
251250
struct fwnode_handle *node;
251+
struct phylink_pcs *pcs;
252252

253253
node = fwnode_find_reference(dpmac_node, "pcs-handle", 0);
254254
if (IS_ERR(node)) {
@@ -257,26 +257,27 @@ static int dpaa2_pcs_create(struct dpaa2_mac *mac,
257257
return 0;
258258
}
259259

260-
if (!fwnode_device_is_available(node)) {
261-
netdev_err(mac->net_dev, "pcs-handle node not available\n");
262-
fwnode_handle_put(node);
263-
return -ENODEV;
264-
}
265-
266-
mdiodev = fwnode_mdio_find_device(node);
260+
pcs = lynx_pcs_create_fwnode(node);
267261
fwnode_handle_put(node);
268-
if (!mdiodev) {
262+
263+
if (pcs == ERR_PTR(-EPROBE_DEFER)) {
269264
netdev_dbg(mac->net_dev, "missing PCS device\n");
270265
return -EPROBE_DEFER;
271266
}
272267

273-
mac->pcs = lynx_pcs_create(mdiodev);
274-
if (!mac->pcs) {
275-
netdev_err(mac->net_dev, "lynx_pcs_create() failed\n");
276-
mdio_device_free(mdiodev);
277-
return -ENOMEM;
268+
if (pcs == ERR_PTR(-ENODEV)) {
269+
netdev_err(mac->net_dev, "pcs-handle node not available\n");
270+
return PTR_ERR(pcs);
271+
}
272+
273+
if (IS_ERR(pcs)) {
274+
netdev_err(mac->net_dev,
275+
"lynx_pcs_create_fwnode() failed: %pe\n", pcs);
276+
return PTR_ERR(pcs);
278277
}
279278

279+
mac->pcs = pcs;
280+
280281
return 0;
281282
}
282283

@@ -285,10 +286,7 @@ static void dpaa2_pcs_destroy(struct dpaa2_mac *mac)
285286
struct phylink_pcs *phylink_pcs = mac->pcs;
286287

287288
if (phylink_pcs) {
288-
struct mdio_device *mdio = lynx_get_mdio_device(phylink_pcs);
289-
290289
lynx_pcs_destroy(phylink_pcs);
291-
mdio_device_free(mdio);
292290
mac->pcs = NULL;
293291
}
294292
}

drivers/net/ethernet/freescale/fman/fman_memac.c

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -976,14 +976,10 @@ static int memac_init(struct fman_mac *memac)
976976

977977
static void pcs_put(struct phylink_pcs *pcs)
978978
{
979-
struct mdio_device *mdiodev;
980-
981979
if (IS_ERR_OR_NULL(pcs))
982980
return;
983981

984-
mdiodev = lynx_get_mdio_device(pcs);
985982
lynx_pcs_destroy(pcs);
986-
mdio_device_free(mdiodev);
987983
}
988984

989985
static int memac_free(struct fman_mac *memac)
@@ -1043,20 +1039,14 @@ static struct phylink_pcs *memac_pcs_create(struct device_node *mac_node,
10431039
int index)
10441040
{
10451041
struct device_node *node;
1046-
struct mdio_device *mdiodev = NULL;
10471042
struct phylink_pcs *pcs;
10481043

10491044
node = of_parse_phandle(mac_node, "pcsphy-handle", index);
1050-
if (node && of_device_is_available(node))
1051-
mdiodev = of_mdio_find_device(node);
1052-
of_node_put(node);
1045+
if (!node)
1046+
return ERR_PTR(-ENODEV);
10531047

1054-
if (!mdiodev)
1055-
return ERR_PTR(-EPROBE_DEFER);
1056-
1057-
pcs = lynx_pcs_create(mdiodev);
1058-
if (!pcs)
1059-
mdio_device_free(mdiodev);
1048+
pcs = lynx_pcs_create_fwnode(of_fwnode_handle(node));
1049+
of_node_put(node);
10601050

10611051
return pcs;
10621052
}

drivers/net/pcs/pcs-lynx.c

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <linux/mdio.h>
77
#include <linux/phylink.h>
88
#include <linux/pcs-lynx.h>
9+
#include <linux/property.h>
910

1011
#define SGMII_CLOCK_PERIOD_NS 8 /* PCS is clocked at 125 MHz */
1112
#define LINK_TIMER_VAL(ns) ((u32)((ns) / SGMII_CLOCK_PERIOD_NS))
@@ -34,14 +35,6 @@ enum sgmii_speed {
3435
#define phylink_pcs_to_lynx(pl_pcs) container_of((pl_pcs), struct lynx_pcs, pcs)
3536
#define lynx_to_phylink_pcs(lynx) (&(lynx)->pcs)
3637

37-
struct mdio_device *lynx_get_mdio_device(struct phylink_pcs *pcs)
38-
{
39-
struct lynx_pcs *lynx = phylink_pcs_to_lynx(pcs);
40-
41-
return lynx->mdio;
42-
}
43-
EXPORT_SYMBOL(lynx_get_mdio_device);
44-
4538
static void lynx_pcs_get_state_usxgmii(struct mdio_device *pcs,
4639
struct phylink_link_state *state)
4740
{
@@ -315,13 +308,13 @@ static const struct phylink_pcs_ops lynx_pcs_phylink_ops = {
315308
.pcs_link_up = lynx_pcs_link_up,
316309
};
317310

318-
struct phylink_pcs *lynx_pcs_create(struct mdio_device *mdio)
311+
static struct phylink_pcs *lynx_pcs_create(struct mdio_device *mdio)
319312
{
320313
struct lynx_pcs *lynx;
321314

322315
lynx = kzalloc(sizeof(*lynx), GFP_KERNEL);
323316
if (!lynx)
324-
return NULL;
317+
return ERR_PTR(-ENOMEM);
325318

326319
mdio_device_get(mdio);
327320
lynx->mdio = mdio;
@@ -330,7 +323,6 @@ struct phylink_pcs *lynx_pcs_create(struct mdio_device *mdio)
330323

331324
return lynx_to_phylink_pcs(lynx);
332325
}
333-
EXPORT_SYMBOL(lynx_pcs_create);
334326

335327
struct phylink_pcs *lynx_pcs_create_mdiodev(struct mii_bus *bus, int addr)
336328
{
@@ -343,11 +335,41 @@ struct phylink_pcs *lynx_pcs_create_mdiodev(struct mii_bus *bus, int addr)
343335

344336
pcs = lynx_pcs_create(mdio);
345337

346-
/* Convert failure to create the PCS to an error pointer, so this
347-
* function has a consistent return value strategy.
338+
/* lynx_create() has taken a refcount on the mdiodev if it was
339+
* successful. If lynx_create() fails, this will free the mdio
340+
* device here. In any case, we don't need to hold our reference
341+
* anymore, and putting it here will allow mdio_device_put() in
342+
* lynx_destroy() to automatically free the mdio device.
348343
*/
349-
if (!pcs)
350-
pcs = ERR_PTR(-ENOMEM);
344+
mdio_device_put(mdio);
345+
346+
return pcs;
347+
}
348+
EXPORT_SYMBOL(lynx_pcs_create_mdiodev);
349+
350+
/*
351+
* lynx_pcs_create_fwnode() creates a lynx PCS instance from the fwnode
352+
* device indicated by node.
353+
*
354+
* Returns:
355+
* -ENODEV if the fwnode is marked unavailable
356+
* -EPROBE_DEFER if we fail to find the device
357+
* -ENOMEM if we fail to allocate memory
358+
* pointer to a phylink_pcs on success
359+
*/
360+
struct phylink_pcs *lynx_pcs_create_fwnode(struct fwnode_handle *node)
361+
{
362+
struct mdio_device *mdio;
363+
struct phylink_pcs *pcs;
364+
365+
if (!fwnode_device_is_available(node))
366+
return ERR_PTR(-ENODEV);
367+
368+
mdio = fwnode_mdio_find_device(node);
369+
if (!mdio)
370+
return ERR_PTR(-EPROBE_DEFER);
371+
372+
pcs = lynx_pcs_create(mdio);
351373

352374
/* lynx_create() has taken a refcount on the mdiodev if it was
353375
* successful. If lynx_create() fails, this will free the mdio
@@ -359,7 +381,7 @@ struct phylink_pcs *lynx_pcs_create_mdiodev(struct mii_bus *bus, int addr)
359381

360382
return pcs;
361383
}
362-
EXPORT_SYMBOL(lynx_pcs_create_mdiodev);
384+
EXPORT_SYMBOL_GPL(lynx_pcs_create_fwnode);
363385

364386
void lynx_pcs_destroy(struct phylink_pcs *pcs)
365387
{

include/linux/pcs-lynx.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,8 @@
99
#include <linux/mdio.h>
1010
#include <linux/phylink.h>
1111

12-
struct mdio_device *lynx_get_mdio_device(struct phylink_pcs *pcs);
13-
14-
struct phylink_pcs *lynx_pcs_create(struct mdio_device *mdio);
1512
struct phylink_pcs *lynx_pcs_create_mdiodev(struct mii_bus *bus, int addr);
13+
struct phylink_pcs *lynx_pcs_create_fwnode(struct fwnode_handle *node);
1614

1715
void lynx_pcs_destroy(struct phylink_pcs *pcs);
1816

0 commit comments

Comments
 (0)