mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 19:21:31 -04:00
i2c: bcm2835: Store pointer to bus clock
commit 3b722da6672df8392f9c43d7c7e04bddd81d7e37 upstream. The commitbebff81fb8("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:bebff81fb8("i2c: bcm2835: Model Divider in CCF") Signed-off-by: Stefan Wahren <[email protected]> Signed-off-by: Wolfram Sang <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
This commit is contained in:
parent
ddd9320a5a
commit
0ca980a82c
1 changed files with 8 additions and 9 deletions
|
|
@ -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 platform_device *pdev)
|
|||
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 platform_device *pdev)
|
|||
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 platform_device *pdev)
|
|||
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 platform_device *pdev)
|
|||
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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue