lkml.org 
[lkml]   [2017]   [Feb]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.16 248/306] net: ethernet: ti: cpsw: fix bad register access in probe error path
    3.16.40-rc1 review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Johan Hovold <johan@kernel.org>

    commit c46ab7e08c79be7400f6d59edbc6f26a91941c5a upstream.

    Make sure to keep the platform device runtime-resumed throughout probe
    to avoid accessing the CPSW registers in the error path (e.g. for
    deferred probe) with clocks disabled:

    Unhandled fault: external abort on non-linefetch (0x1008) at 0xd0872d08
    ...
    [<c04fabcc>] (cpsw_ale_control_set) from [<c04fb8b4>] (cpsw_ale_destroy+0x2c/0x44)
    [<c04fb8b4>] (cpsw_ale_destroy) from [<c04fea58>] (cpsw_probe+0xbd0/0x10c4)
    [<c04fea58>] (cpsw_probe) from [<c047b2a0>] (platform_drv_probe+0x5c/0xc0)

    Fixes: df828598a755 ("netdev: driver: ethernet: Add TI CPSW driver")
    Signed-off-by: Johan Hovold <johan@kernel.org>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    [bwh: Backported to 3.16:
    - s/cpsw->/priv->/g
    - Adjust context]
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    drivers/net/ethernet/ti/cpsw.c | 11 +++++++----
    1 file changed, 7 insertions(+), 4 deletions(-)

    --- a/drivers/net/ethernet/ti/cpsw.c
    +++ b/drivers/net/ethernet/ti/cpsw.c
    @@ -2140,13 +2140,12 @@ static int cpsw_probe(struct platform_de
    */
    pm_runtime_get_sync(&pdev->dev);
    priv->version = readl(&priv->regs->id_ver);
    - pm_runtime_put_sync(&pdev->dev);

    res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
    priv->wr_regs = devm_ioremap_resource(&pdev->dev, res);
    if (IS_ERR(priv->wr_regs)) {
    ret = PTR_ERR(priv->wr_regs);
    - goto clean_runtime_disable_ret;
    + goto clean_pm_runtime_put_ret;
    }

    memset(&dma_params, 0, sizeof(dma_params));
    @@ -2183,7 +2182,7 @@ static int cpsw_probe(struct platform_de
    default:
    dev_err(priv->dev, "unknown version 0x%08x\n", priv->version);
    ret = -ENODEV;
    - goto clean_runtime_disable_ret;
    + goto clean_pm_runtime_put_ret;
    }
    for (i = 0; i < priv->data.slaves; i++) {
    struct cpsw_slave *slave = &priv->slaves[i];
    @@ -2211,7 +2210,7 @@ static int cpsw_probe(struct platform_de
    if (!priv->dma) {
    dev_err(priv->dev, "error initializing dma\n");
    ret = -ENOMEM;
    - goto clean_runtime_disable_ret;
    + goto clean_pm_runtime_put_ret;
    }

    priv->txch = cpdma_chan_create(priv->dma, tx_chan_num(0),
    @@ -2283,6 +2282,8 @@ static int cpsw_probe(struct platform_de
    }
    }

    + pm_runtime_put(&pdev->dev);
    +
    return 0;

    clean_ale_ret:
    @@ -2291,6 +2292,8 @@ clean_dma_ret:
    cpdma_chan_destroy(priv->txch);
    cpdma_chan_destroy(priv->rxch);
    cpdma_ctlr_destroy(priv->dma);
    +clean_pm_runtime_put_ret:
    + pm_runtime_put_sync(&pdev->dev);
    clean_runtime_disable_ret:
    pm_runtime_disable(&pdev->dev);
    clean_ndev_ret:
    \
     
     \ /
      Last update: 2017-02-16 01:24    [W:4.815 / U:0.276 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site