diff options
Diffstat (limited to 'target/linux/brcm2708/patches-4.19/950-0636-i2c-bcm2835-Ensure-clock-exists-when-probing.patch')
-rw-r--r-- | target/linux/brcm2708/patches-4.19/950-0636-i2c-bcm2835-Ensure-clock-exists-when-probing.patch | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/target/linux/brcm2708/patches-4.19/950-0636-i2c-bcm2835-Ensure-clock-exists-when-probing.patch b/target/linux/brcm2708/patches-4.19/950-0636-i2c-bcm2835-Ensure-clock-exists-when-probing.patch new file mode 100644 index 0000000000..4a468f0291 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0636-i2c-bcm2835-Ensure-clock-exists-when-probing.patch @@ -0,0 +1,72 @@ +From 1a5122f1756ef4fc5779324ad26b6a04142166b5 Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond <nh6z@nh6z.net> +Date: Fri, 21 Jun 2019 03:52:50 -0700 +Subject: [PATCH] i2c: bcm2835: Ensure clock exists when probing + +Commit 9de93b04df16b055824e3f1f13fedb90fbcf2e4f upstream. + +Probe function fails to recognize that upstream clock actually +doesn't yet exist because clock driver has not been initialized. +Actually try to go get the clock and test for its existence +before trying to set up a downstream clock based upon it. + +This fixes a bug that causes the i2c driver not to work with +monolithic kernels. + +Fixes: bebff81fb8b9 ("i2c: bcm2835: Model Divider in CCF") +Signed-off-by: Annaliese McDermond <nh6z@nh6z.net> +Acked-by: Stefan Wahren <wahrenst@gmx.net> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +--- + drivers/i2c/busses/i2c-bcm2835.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +--- a/drivers/i2c/busses/i2c-bcm2835.c ++++ b/drivers/i2c/busses/i2c-bcm2835.c +@@ -244,15 +244,18 @@ static const struct clk_ops clk_bcm2835_ + }; + + static struct clk *bcm2835_i2c_register_div(struct device *dev, +- const char *mclk_name, ++ struct clk *mclk, + struct bcm2835_i2c_dev *i2c_dev) + { + struct clk_init_data init; + struct clk_bcm2835_i2c *priv; + char name[32]; ++ const char *mclk_name; + + snprintf(name, sizeof(name), "%s_div", dev_name(dev)); + ++ mclk_name = __clk_get_name(mclk); ++ + init.ops = &clk_bcm2835_i2c_ops; + init.name = name; + init.parent_names = (const char* []) { mclk_name }; +@@ -505,8 +508,8 @@ static int bcm2835_i2c_probe(struct plat + struct resource *mem, *irq; + int ret; + struct i2c_adapter *adap; +- const char *mclk_name; + struct clk *bus_clk; ++ struct clk *mclk; + u32 bus_clk_rate; + + i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); +@@ -521,9 +524,14 @@ static int bcm2835_i2c_probe(struct plat + if (IS_ERR(i2c_dev->regs)) + return PTR_ERR(i2c_dev->regs); + +- mclk_name = of_clk_get_parent_name(pdev->dev.of_node, 0); ++ mclk = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(mclk)) { ++ if (PTR_ERR(mclk) != -EPROBE_DEFER) ++ dev_err(&pdev->dev, "Could not get clock\n"); ++ return PTR_ERR(mclk); ++ } + +- bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk_name, i2c_dev); ++ bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk, i2c_dev); + + if (IS_ERR(bus_clk)) { + dev_err(&pdev->dev, "Could not register clock\n"); |