2019-09-19 14:43:19 +00:00
|
|
|
From 1a5122f1756ef4fc5779324ad26b6a04142166b5 Mon Sep 17 00:00:00 2001
|
2019-07-09 18:32:28 +00:00
|
|
|
From: Annaliese McDermond <nh6z@nh6z.net>
|
|
|
|
Date: Fri, 21 Jun 2019 03:52:50 -0700
|
2019-12-23 12:42:55 +00:00
|
|
|
Subject: [PATCH] i2c: bcm2835: Ensure clock exists when probing
|
2019-07-09 18:32:28 +00:00
|
|
|
|
|
|
|
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");
|