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 5.4 008/203] i2c: bcm2835: Store pointer to bus clock
    Date
    From: Stefan Wahren <wahrenst@gmx.net>

    commit 3b722da6672df8392f9c43d7c7e04bddd81d7e37 upstream.

    The commit bebff81fb8b9 ("i2c: bcm2835: Model Divider in CCF") introduced
    a NULL pointer dereference on driver unload. It seems that we can't fetch
    the bus clock via devm_clk_get in bcm2835_i2c_remove. As an alternative
    approach store a pointer to the bus clock in the private driver structure.

    Fixes: bebff81fb8b9 ("i2c: bcm2835: Model Divider in CCF")
    Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
    Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/i2c/busses/i2c-bcm2835.c | 17 ++++++++---------
    1 file changed, 8 insertions(+), 9 deletions(-)

    --- a/drivers/i2c/busses/i2c-bcm2835.c
    +++ b/drivers/i2c/busses/i2c-bcm2835.c
    @@ -58,6 +58,7 @@ struct bcm2835_i2c_dev {
    struct i2c_adapter adapter;
    struct completion completion;
    struct i2c_msg *curr_msg;
    + struct clk *bus_clk;
    int num_msgs;
    u32 msg_err;
    u8 *msg_buf;
    @@ -404,7 +405,6 @@ static int bcm2835_i2c_probe(struct plat
    struct resource *mem, *irq;
    int ret;
    struct i2c_adapter *adap;
    - struct clk *bus_clk;
    struct clk *mclk;
    u32 bus_clk_rate;

    @@ -427,11 +427,11 @@ static int bcm2835_i2c_probe(struct plat
    return PTR_ERR(mclk);
    }

    - bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk, i2c_dev);
    + i2c_dev->bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk, i2c_dev);

    - if (IS_ERR(bus_clk)) {
    + if (IS_ERR(i2c_dev->bus_clk)) {
    dev_err(&pdev->dev, "Could not register clock\n");
    - return PTR_ERR(bus_clk);
    + return PTR_ERR(i2c_dev->bus_clk);
    }

    ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency",
    @@ -442,13 +442,13 @@ static int bcm2835_i2c_probe(struct plat
    bus_clk_rate = 100000;
    }

    - ret = clk_set_rate_exclusive(bus_clk, bus_clk_rate);
    + ret = clk_set_rate_exclusive(i2c_dev->bus_clk, bus_clk_rate);
    if (ret < 0) {
    dev_err(&pdev->dev, "Could not set clock frequency\n");
    return ret;
    }

    - ret = clk_prepare_enable(bus_clk);
    + ret = clk_prepare_enable(i2c_dev->bus_clk);
    if (ret) {
    dev_err(&pdev->dev, "Couldn't prepare clock");
    return ret;
    @@ -491,10 +491,9 @@ static int bcm2835_i2c_probe(struct plat
    static int bcm2835_i2c_remove(struct platform_device *pdev)
    {
    struct bcm2835_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
    - struct clk *bus_clk = devm_clk_get(i2c_dev->dev, "div");

    - clk_rate_exclusive_put(bus_clk);
    - clk_disable_unprepare(bus_clk);
    + clk_rate_exclusive_put(i2c_dev->bus_clk);
    + clk_disable_unprepare(i2c_dev->bus_clk);

    free_irq(i2c_dev->irq, i2c_dev);
    i2c_del_adapter(&i2c_dev->adapter);

    \
     
     \ /
      Last update: 2020-01-17 00:20    [W:2.256 / U:0.316 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site