Skip to content

Commit 3b722da

Browse files
lategoodbyeWolfram Sang
authored andcommitted
i2c: bcm2835: Store pointer to bus clock
The commit bebff81 ("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: bebff81 ("i2c: bcm2835: Model Divider in CCF") Signed-off-by: Stefan Wahren <[email protected]> Signed-off-by: Wolfram Sang <[email protected]>
1 parent 42052d9 commit 3b722da

File tree

1 file changed

+8
-9
lines changed

1 file changed

+8
-9
lines changed

drivers/i2c/busses/i2c-bcm2835.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ struct bcm2835_i2c_dev {
5858
struct i2c_adapter adapter;
5959
struct completion completion;
6060
struct i2c_msg *curr_msg;
61+
struct clk *bus_clk;
6162
int num_msgs;
6263
u32 msg_err;
6364
u8 *msg_buf;
@@ -404,7 +405,6 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
404405
struct resource *mem, *irq;
405406
int ret;
406407
struct i2c_adapter *adap;
407-
struct clk *bus_clk;
408408
struct clk *mclk;
409409
u32 bus_clk_rate;
410410

@@ -427,11 +427,11 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
427427
return PTR_ERR(mclk);
428428
}
429429

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

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

437437
ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency",
@@ -442,13 +442,13 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
442442
bus_clk_rate = 100000;
443443
}
444444

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

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

496-
clk_rate_exclusive_put(bus_clk);
497-
clk_disable_unprepare(bus_clk);
495+
clk_rate_exclusive_put(i2c_dev->bus_clk);
496+
clk_disable_unprepare(i2c_dev->bus_clk);
498497

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

0 commit comments

Comments
 (0)