lkml.org 
[lkml]   [2020]   [Jan]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.19 450/671] fsi/core: Fix error paths on CFAM init
    Date
    From: Jeremy Kerr <jk@ozlabs.org>

    [ Upstream commit 371975b0b07520c85098652d561639837a60a905 ]

    Change d1dcd67825 re-worked the struct fsi_slave initialisation in
    fsi_slave_init, but introduced a few inconsitencies: the slave->dev is
    now registered through cdev_device_add, but we may kfree() the device
    out from underneath the cdev registration. We may also leave an IDA
    allocated.

    This change fixes the error paths, so that we kfree() only before the
    device is registered with the core code. We also move the smode write to
    before we start creating proper devices, as it's the most likely to
    fail. We also remove the IDA-allocated minor on error, and properly
    clean up the of_node.

    Fixes: d1dcd6782576 ("fsi: Add cfam char devices")
    Reported-by: Lei YU <mine260309@gmail.com>
    Tested-by: John Wang <wangzqbj@inspur.com>
    Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
    Signed-off-by: Joel Stanley <joel@jms.id.au>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/fsi/fsi-core.c | 32 ++++++++++++++++++++------------
    1 file changed, 20 insertions(+), 12 deletions(-)

    diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
    index c6fa9b393e84..bd62236d3f97 100644
    --- a/drivers/fsi/fsi-core.c
    +++ b/drivers/fsi/fsi-core.c
    @@ -1060,6 +1060,14 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)

    }

    + rc = fsi_slave_set_smode(slave);
    + if (rc) {
    + dev_warn(&master->dev,
    + "can't set smode on slave:%02x:%02x %d\n",
    + link, id, rc);
    + goto err_free;
    + }
    +
    /* Allocate a minor in the FSI space */
    rc = __fsi_get_new_minor(slave, fsi_dev_cfam, &slave->dev.devt,
    &slave->cdev_idx);
    @@ -1071,17 +1079,14 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
    rc = cdev_device_add(&slave->cdev, &slave->dev);
    if (rc) {
    dev_err(&slave->dev, "Error %d creating slave device\n", rc);
    - goto err_free;
    + goto err_free_ida;
    }

    - rc = fsi_slave_set_smode(slave);
    - if (rc) {
    - dev_warn(&master->dev,
    - "can't set smode on slave:%02x:%02x %d\n",
    - link, id, rc);
    - kfree(slave);
    - return -ENODEV;
    - }
    + /* Now that we have the cdev registered with the core, any fatal
    + * failures beyond this point will need to clean up through
    + * cdev_device_del(). Fortunately though, nothing past here is fatal.
    + */
    +
    if (master->link_config)
    master->link_config(master, link,
    slave->t_send_delay,
    @@ -1098,10 +1103,13 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
    dev_dbg(&master->dev, "failed during slave scan with: %d\n",
    rc);

    - return rc;
    + return 0;

    - err_free:
    - put_device(&slave->dev);
    +err_free_ida:
    + fsi_free_minor(slave->dev.devt);
    +err_free:
    + of_node_put(slave->dev.of_node);
    + kfree(slave);
    return rc;
    }

    --
    2.20.1
    \
     
     \ /
      Last update: 2020-01-16 18:10    [W:4.059 / U:0.548 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site