diff options
Diffstat (limited to 'target/linux/brcm2708/patches-4.19/950-0635-i2c-bcm2835-Move-IRQ-request-after-clock-code-in-pro.patch')
-rw-r--r-- | target/linux/brcm2708/patches-4.19/950-0635-i2c-bcm2835-Move-IRQ-request-after-clock-code-in-pro.patch | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/target/linux/brcm2708/patches-4.19/950-0635-i2c-bcm2835-Move-IRQ-request-after-clock-code-in-pro.patch b/target/linux/brcm2708/patches-4.19/950-0635-i2c-bcm2835-Move-IRQ-request-after-clock-code-in-pro.patch new file mode 100644 index 0000000000..b363e753ea --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0635-i2c-bcm2835-Move-IRQ-request-after-clock-code-in-pro.patch @@ -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; |