Commit b793f081 authored by Christian Lamparter's avatar Christian Lamparter Committed by David S. Miller

net: ibm: emac: fix regression caused by emac_dt_phy_probe()

Julian Margetson reported a panic on his SAM460EX with Kernel 4.11-rc1:
| Unable to handle kernel paging request for data at address 0x00000014
| Oops: Kernel access of bad area, sig: 11 [#1]
| PREEMPT
| Canyonlands
| Modules linked in:
| CPU: 0 PID: 1 Comm: swapper Not tainted [...]
| task: ea838000 task.stack: ea836000
| NIP: c0599f5c LR: c0599dd8 CTR: 00000000
| REGS: ea837c80 TRAP: 0300   Not tainted [...]
| MSR: 00029000 <CE,EE,ME>
|  CR: 24371242  XER: 20000000
| DEAR: 00000014 ESR: 00000000
| GPR00: c0599ce8 ea837d30 ea838000 c0e52dcc c0d56ffb [...]
| NIP [c0599f5c] emac_probe+0xfb4/0x1304
| LR [c0599dd8] emac_probe+0xe30/0x1304
| Call Trace:
| [ea837d30] [c0599ce8] emac_probe+0xd40/0x1304 (unreliable)
| [ea837d80] [c0533504] platform_drv_probe+0x48/0x90
| [ea837da0] [c0531c14] driver_probe_device+0x15c/0x2c4
| [ea837dd0] [c0531e04] __driver_attach+0x88/0xb0
| ---[ end trace ... ]---

The problem is caused by emac_dt_phy_probe() returing success (0)
for existing device-trees configurations that do not specify a
"phy-handle" property. This caused the code to skip the existing
phy probe and setup. Which led to essential phy related
data-structures being uninitialized.

This patch also removes the unused variable in emac_dt_phy_connect().

Fixes: a577ca6b ("net: emac: add support for device-tree based PHY discovery and setup")
Reported-by: default avatarJulian Margetson <runaway@candw.ms>
Signed-off-by: default avatarChristian Lamparter <chunkeey@googlemail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 50ad480e
...@@ -2589,8 +2589,6 @@ static int emac_dt_mdio_probe(struct emac_instance *dev) ...@@ -2589,8 +2589,6 @@ static int emac_dt_mdio_probe(struct emac_instance *dev)
static int emac_dt_phy_connect(struct emac_instance *dev, static int emac_dt_phy_connect(struct emac_instance *dev,
struct device_node *phy_handle) struct device_node *phy_handle)
{ {
int res;
dev->phy.def = devm_kzalloc(&dev->ofdev->dev, sizeof(*dev->phy.def), dev->phy.def = devm_kzalloc(&dev->ofdev->dev, sizeof(*dev->phy.def),
GFP_KERNEL); GFP_KERNEL);
if (!dev->phy.def) if (!dev->phy.def)
...@@ -2617,7 +2615,7 @@ static int emac_dt_phy_probe(struct emac_instance *dev) ...@@ -2617,7 +2615,7 @@ static int emac_dt_phy_probe(struct emac_instance *dev)
{ {
struct device_node *np = dev->ofdev->dev.of_node; struct device_node *np = dev->ofdev->dev.of_node;
struct device_node *phy_handle; struct device_node *phy_handle;
int res = 0; int res = 1;
phy_handle = of_parse_phandle(np, "phy-handle", 0); phy_handle = of_parse_phandle(np, "phy-handle", 0);
...@@ -2714,14 +2712,25 @@ static int emac_init_phy(struct emac_instance *dev) ...@@ -2714,14 +2712,25 @@ static int emac_init_phy(struct emac_instance *dev)
if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII)) { if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII)) {
int res = emac_dt_phy_probe(dev); int res = emac_dt_phy_probe(dev);
switch (res) {
case 1:
/* No phy-handle property configured.
* Continue with the existing phy probe
* and setup code.
*/
break;
case 0:
mutex_unlock(&emac_phy_map_lock); mutex_unlock(&emac_phy_map_lock);
if (!res)
goto init_phy; goto init_phy;
default:
mutex_unlock(&emac_phy_map_lock);
dev_err(&dev->ofdev->dev, "failed to attach dt phy (%d).\n", dev_err(&dev->ofdev->dev, "failed to attach dt phy (%d).\n",
res); res);
return res; return res;
} }
}
if (dev->phy_address != 0xffffffff) if (dev->phy_address != 0xffffffff)
phy_map = ~(1 << dev->phy_address); phy_map = ~(1 << dev->phy_address);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment