diff options
author | Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> | 2018-01-03 12:09:49 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-01-04 14:17:34 -0500 |
commit | dfe8266b8dd10e12a731c985b725fcf7f0e537f0 (patch) | |
tree | c8afb7deacfa605fec1e1e2f46f24041eb124183 | |
parent | 879626e3a52630316d817cbda7cec9a5446d1d82 (diff) |
sh_eth: fix TSU resource handling
When switching the driver to the managed device API, I managed to break
the case of a dual Ether devices sharing a single TSU: the 2nd Ether port
wouldn't probe. Iwamatsu-san has tried to fix this but his patch was buggy
and he then dropped the ball...
The solution is to limit calling devm_request_mem_region() to the first
of the two ports sharing the same TSU, so devm_ioremap_resource() can't
be used anymore for the TSU resource...
Fixes: d5e07e69218f ("sh_eth: use managed device API")
Reported-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/renesas/sh_eth.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 75323000c364..1bdd67a8a869 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c | |||
@@ -3225,10 +3225,29 @@ static int sh_eth_drv_probe(struct platform_device *pdev) | |||
3225 | /* ioremap the TSU registers */ | 3225 | /* ioremap the TSU registers */ |
3226 | if (mdp->cd->tsu) { | 3226 | if (mdp->cd->tsu) { |
3227 | struct resource *rtsu; | 3227 | struct resource *rtsu; |
3228 | |||
3228 | rtsu = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 3229 | rtsu = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
3229 | mdp->tsu_addr = devm_ioremap_resource(&pdev->dev, rtsu); | 3230 | if (!rtsu) { |
3230 | if (IS_ERR(mdp->tsu_addr)) { | 3231 | dev_err(&pdev->dev, "no TSU resource\n"); |
3231 | ret = PTR_ERR(mdp->tsu_addr); | 3232 | ret = -ENODEV; |
3233 | goto out_release; | ||
3234 | } | ||
3235 | /* We can only request the TSU region for the first port | ||
3236 | * of the two sharing this TSU for the probe to succeed... | ||
3237 | */ | ||
3238 | if (devno % 2 == 0 && | ||
3239 | !devm_request_mem_region(&pdev->dev, rtsu->start, | ||
3240 | resource_size(rtsu), | ||
3241 | dev_name(&pdev->dev))) { | ||
3242 | dev_err(&pdev->dev, "can't request TSU resource.\n"); | ||
3243 | ret = -EBUSY; | ||
3244 | goto out_release; | ||
3245 | } | ||
3246 | mdp->tsu_addr = devm_ioremap(&pdev->dev, rtsu->start, | ||
3247 | resource_size(rtsu)); | ||
3248 | if (!mdp->tsu_addr) { | ||
3249 | dev_err(&pdev->dev, "TSU region ioremap() failed.\n"); | ||
3250 | ret = -ENOMEM; | ||
3232 | goto out_release; | 3251 | goto out_release; |
3233 | } | 3252 | } |
3234 | mdp->port = devno % 2; | 3253 | mdp->port = devno % 2; |