brcm2708: organize kernel patches
[openwrt/staging/dedeckeh.git] / target / linux / brcm2708 / patches-4.19 / 950-0636-i2c-bcm2835-Ensure-clock-exists-when-probing.patch
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 (file)
index 0000000..4a468f0
--- /dev/null
@@ -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");