* [PATCH v2 net-next] net: phy: adjust fixed_phy_register() return value
@ 2014-10-06 18:38 Petri Gynther
2014-10-07 4:07 ` David Miller
0 siblings, 1 reply; 4+ messages in thread
From: Petri Gynther @ 2014-10-06 18:38 UTC (permalink / raw)
To: netdev; +Cc: davem, f.fainelli, thomas.petazzoni
Adjust fixed_phy_register() to return struct phy_device *, so that
it becomes easy to use fixed PHYs without device tree support:
phydev = fixed_phy_register(PHY_POLL, &fixed_phy_status, NULL);
fixed_phy_set_link_update(phydev, fixed_phy_link_update);
phy_connect_direct(netdev, phydev, handler_fn, phy_interface);
This change is a prerequisite for modifying bcmgenet driver to work
without a device tree on Broadcom's MIPS-based 7xxx platforms.
Signed-off-by: Petri Gynther <pgynther@google.com>
---
drivers/net/phy/fixed.c | 16 ++++++++--------
drivers/of/of_mdio.c | 7 +++++--
include/linux/phy_fixed.h | 14 +++++++-------
3 files changed, 20 insertions(+), 17 deletions(-)
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index 5b19fbb..47872caa 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -233,9 +233,9 @@ EXPORT_SYMBOL_GPL(fixed_phy_del);
static int phy_fixed_addr;
static DEFINE_SPINLOCK(phy_fixed_addr_lock);
-int fixed_phy_register(unsigned int irq,
- struct fixed_phy_status *status,
- struct device_node *np)
+struct phy_device *fixed_phy_register(unsigned int irq,
+ struct fixed_phy_status *status,
+ struct device_node *np)
{
struct fixed_mdio_bus *fmb = &platform_fmb;
struct phy_device *phy;
@@ -246,19 +246,19 @@ int fixed_phy_register(unsigned int irq,
spin_lock(&phy_fixed_addr_lock);
if (phy_fixed_addr == PHY_MAX_ADDR) {
spin_unlock(&phy_fixed_addr_lock);
- return -ENOSPC;
+ return ERR_PTR(-ENOSPC);
}
phy_addr = phy_fixed_addr++;
spin_unlock(&phy_fixed_addr_lock);
ret = fixed_phy_add(PHY_POLL, phy_addr, status);
if (ret < 0)
- return ret;
+ return ERR_PTR(ret);
phy = get_phy_device(fmb->mii_bus, phy_addr, false);
if (!phy || IS_ERR(phy)) {
fixed_phy_del(phy_addr);
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
}
of_node_get(np);
@@ -269,10 +269,10 @@ int fixed_phy_register(unsigned int irq,
phy_device_free(phy);
of_node_put(np);
fixed_phy_del(phy_addr);
- return ret;
+ return ERR_PTR(ret);
}
- return 0;
+ return phy;
}
static int __init fixed_mdio_bus_init(void)
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index a85d800..1bd4305 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -286,6 +286,7 @@ int of_phy_register_fixed_link(struct device_node *np)
struct device_node *fixed_link_node;
const __be32 *fixed_link_prop;
int len;
+ struct phy_device *phy;
/* New binding */
fixed_link_node = of_get_child_by_name(np, "fixed-link");
@@ -299,7 +300,8 @@ int of_phy_register_fixed_link(struct device_node *np)
status.asym_pause = of_property_read_bool(fixed_link_node,
"asym-pause");
of_node_put(fixed_link_node);
- return fixed_phy_register(PHY_POLL, &status, np);
+ phy = fixed_phy_register(PHY_POLL, &status, np);
+ return IS_ERR(phy) ? PTR_ERR(phy) : 0;
}
/* Old binding */
@@ -310,7 +312,8 @@ int of_phy_register_fixed_link(struct device_node *np)
status.speed = be32_to_cpu(fixed_link_prop[2]);
status.pause = be32_to_cpu(fixed_link_prop[3]);
status.asym_pause = be32_to_cpu(fixed_link_prop[4]);
- return fixed_phy_register(PHY_POLL, &status, np);
+ phy = fixed_phy_register(PHY_POLL, &status, np);
+ return IS_ERR(phy) ? PTR_ERR(phy) : 0;
}
return -ENODEV;
diff --git a/include/linux/phy_fixed.h b/include/linux/phy_fixed.h
index 9411386..f2ca1b4 100644
--- a/include/linux/phy_fixed.h
+++ b/include/linux/phy_fixed.h
@@ -14,9 +14,9 @@ struct device_node;
#ifdef CONFIG_FIXED_PHY
extern int fixed_phy_add(unsigned int irq, int phy_id,
struct fixed_phy_status *status);
-extern int fixed_phy_register(unsigned int irq,
- struct fixed_phy_status *status,
- struct device_node *np);
+extern struct phy_device *fixed_phy_register(unsigned int irq,
+ struct fixed_phy_status *status,
+ struct device_node *np);
extern void fixed_phy_del(int phy_addr);
extern int fixed_phy_set_link_update(struct phy_device *phydev,
int (*link_update)(struct net_device *,
@@ -27,11 +27,11 @@ static inline int fixed_phy_add(unsigned int irq, int phy_id,
{
return -ENODEV;
}
-static inline int fixed_phy_register(unsigned int irq,
- struct fixed_phy_status *status,
- struct device_node *np)
+static inline struct phy_device *fixed_phy_register(unsigned int irq,
+ struct fixed_phy_status *status,
+ struct device_node *np)
{
- return -ENODEV;
+ return ERR_PTR(-ENODEV);
}
static inline int fixed_phy_del(int phy_addr)
{
--
2.1.0.rc2.206.gedb03e5
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v2 net-next] net: phy: adjust fixed_phy_register() return value
2014-10-06 18:38 [PATCH v2 net-next] net: phy: adjust fixed_phy_register() return value Petri Gynther
@ 2014-10-07 4:07 ` David Miller
2014-10-07 16:48 ` Petri Gynther
[not found] ` <CAGXr9JF8fx6YH3szY=nwxTJeJgopBCW9Kzhcs33q4oFG5GNOBQ@mail.gmail.com>
0 siblings, 2 replies; 4+ messages in thread
From: David Miller @ 2014-10-07 4:07 UTC (permalink / raw)
To: pgynther; +Cc: netdev, f.fainelli, thomas.petazzoni
From: Petri Gynther <pgynther@google.com>
Date: Mon, 6 Oct 2014 11:38:30 -0700 (PDT)
> Adjust fixed_phy_register() to return struct phy_device *, so that
> it becomes easy to use fixed PHYs without device tree support:
>
> phydev = fixed_phy_register(PHY_POLL, &fixed_phy_status, NULL);
> fixed_phy_set_link_update(phydev, fixed_phy_link_update);
> phy_connect_direct(netdev, phydev, handler_fn, phy_interface);
>
> This change is a prerequisite for modifying bcmgenet driver to work
> without a device tree on Broadcom's MIPS-based 7xxx platforms.
>
> Signed-off-by: Petri Gynther <pgynther@google.com>
If the caller gets this 'phy' pointer and does something with it,
something seems amiss.
We don't hold an extra reference to the 'phy' object for the caller,
so another thread of control can unregister it and kill that last
reference and therefore free it up.
I think to be legitimate, you have to hold an extra reference on
'phy' for the caller. And now that means that code paths that
don't need to do anything with 'phy' now will need to release
that reference.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2 net-next] net: phy: adjust fixed_phy_register() return value
2014-10-07 4:07 ` David Miller
@ 2014-10-07 16:48 ` Petri Gynther
[not found] ` <CAGXr9JF8fx6YH3szY=nwxTJeJgopBCW9Kzhcs33q4oFG5GNOBQ@mail.gmail.com>
1 sibling, 0 replies; 4+ messages in thread
From: Petri Gynther @ 2014-10-07 16:48 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Florian Fainelli, Thomas Petazzoni
Hi David,
On Mon, Oct 6, 2014 at 9:07 PM, David Miller <davem@davemloft.net> wrote:
> From: Petri Gynther <pgynther@google.com>
> Date: Mon, 6 Oct 2014 11:38:30 -0700 (PDT)
>
>> Adjust fixed_phy_register() to return struct phy_device *, so that
>> it becomes easy to use fixed PHYs without device tree support:
>>
>> phydev = fixed_phy_register(PHY_POLL, &fixed_phy_status, NULL);
>> fixed_phy_set_link_update(phydev, fixed_phy_link_update);
>> phy_connect_direct(netdev, phydev, handler_fn, phy_interface);
>>
>> This change is a prerequisite for modifying bcmgenet driver to work
>> without a device tree on Broadcom's MIPS-based 7xxx platforms.
>>
>> Signed-off-by: Petri Gynther <pgynther@google.com>
>
> If the caller gets this 'phy' pointer and does something with it,
> something seems amiss.
>
> We don't hold an extra reference to the 'phy' object for the caller,
> so another thread of control can unregister it and kill that last
> reference and therefore free it up.
>
> I think to be legitimate, you have to hold an extra reference on
> 'phy' for the caller. And now that means that code paths that
> don't need to do anything with 'phy' now will need to release
> that reference.
I'm not sure if I understand your comment. The caller of
fixed_phy_register() now gets the pointer to the phydev created by
get_phy_device(). What other thread is aware of this pointer and how
could they free it? Isn't the caller of fixed_phy_register()
exclusively in charge of the created phydev?
I'm trying to make fixed_phy_device() more convenient to use, so that
drivers don't need to make separate calls to fixed_phy_add() +
get_phy_device() + phy_device_register().
-- Petri
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2 net-next] net: phy: adjust fixed_phy_register() return value
[not found] ` <CAGXr9JF8fx6YH3szY=nwxTJeJgopBCW9Kzhcs33q4oFG5GNOBQ@mail.gmail.com>
@ 2014-10-07 17:02 ` David Miller
0 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2014-10-07 17:02 UTC (permalink / raw)
To: pgynther; +Cc: netdev, f.fainelli, thomas.petazzoni
From: Petri Gynther <pgynther@google.com>
Date: Tue, 7 Oct 2014 09:47:37 -0700
> I'm not sure if I understand your comment. The caller of
> fixed_phy_register() now gets the pointer to the phydev created by
> get_phy_device(). What other thread is aware of this pointer and how could
> they free it? Isn't the caller of fixed_phy_register() exclusively in
> charge of the created phydev?
If this is the case then my concerns are unfounded.
Thanks for clearing that up and I'll apply your patch, thanks!
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2014-10-07 17:02 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-10-06 18:38 [PATCH v2 net-next] net: phy: adjust fixed_phy_register() return value Petri Gynther
2014-10-07 4:07 ` David Miller
2014-10-07 16:48 ` Petri Gynther
[not found] ` <CAGXr9JF8fx6YH3szY=nwxTJeJgopBCW9Kzhcs33q4oFG5GNOBQ@mail.gmail.com>
2014-10-07 17:02 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).