brcm2708: update to latest patches from RPi Foundation
[openwrt/staging/dedeckeh.git] / target / linux / brcm2708 / patches-4.19 / 950-0607-i2c-bcm2835-Move-IRQ-request-after-clock-code-in-pro.patch
diff --git a/target/linux/brcm2708/patches-4.19/950-0607-i2c-bcm2835-Move-IRQ-request-after-clock-code-in-pro.patch b/target/linux/brcm2708/patches-4.19/950-0607-i2c-bcm2835-Move-IRQ-request-after-clock-code-in-pro.patch
new file mode 100644 (file)
index 0000000..b363e75
--- /dev/null
@@ -0,0 +1,66 @@
+From 614cade3a68f7214939e1c72acd5fcc9d49beeef Mon Sep 17 00:00:00 2001
+From: Annaliese McDermond <nh6z@nh6z.net>
+Date: Fri, 21 Jun 2019 03:52:49 -0700
+Subject: [PATCH] i2c: bcm2835: Move IRQ request after clock code in
+ probe
+
+Commit 4a5cfa39465cad25dd736d7ceba8a5d32eea4ecc upstream.
+
+If any of the clock code in the probe fails and returns, the IRQ
+will not be freed.  Moving the IRQ request to last allows it to
+be freed on any errors further up in the probe function.  devm_
+calls can apparently not be used because there are some potential
+race conditions that will arise.
+
+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 | 28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-bcm2835.c
++++ b/drivers/i2c/busses/i2c-bcm2835.c
+@@ -521,20 +521,6 @@ static int bcm2835_i2c_probe(struct plat
+       if (IS_ERR(i2c_dev->regs))
+               return PTR_ERR(i2c_dev->regs);
+-      irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+-      if (!irq) {
+-              dev_err(&pdev->dev, "No IRQ resource\n");
+-              return -ENODEV;
+-      }
+-      i2c_dev->irq = irq->start;
+-
+-      ret = request_irq(i2c_dev->irq, bcm2835_i2c_isr, IRQF_SHARED,
+-                        dev_name(&pdev->dev), i2c_dev);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Could not request IRQ\n");
+-              return -ENODEV;
+-      }
+-
+       mclk_name = of_clk_get_parent_name(pdev->dev.of_node, 0);
+       bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk_name, i2c_dev);
+@@ -564,6 +550,20 @@ static int bcm2835_i2c_probe(struct plat
+               return ret;
+       }
++      irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
++      if (!irq) {
++              dev_err(&pdev->dev, "No IRQ resource\n");
++              return -ENODEV;
++      }
++      i2c_dev->irq = irq->start;
++
++      ret = request_irq(i2c_dev->irq, bcm2835_i2c_isr, IRQF_SHARED,
++                        dev_name(&pdev->dev), i2c_dev);
++      if (ret) {
++              dev_err(&pdev->dev, "Could not request IRQ\n");
++              return -ENODEV;
++      }
++
+       adap = &i2c_dev->adapter;
+       i2c_set_adapdata(adap, i2c_dev);
+       adap->owner = THIS_MODULE;