1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
From 93ba2aeb9ad3899e2b72877daa47376a6bf192b6 Mon Sep 17 00:00:00 2001
From: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
Date: Mon, 23 Sep 2019 13:48:49 -0700
Subject: [PATCH] Refine initialization flow in I2C driver
Since we enabled I2C busses in u-boot, we need to disable the I2C
bus and clear all garbage interrupts when kernel probes the bus.
This commit refines the initialization flow by adding a bus reset
at the beginning of probe function and by moving bus init function
after interrupt handling setup.
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
---
drivers/i2c/busses/i2c-aspeed.c | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
index a308d5896632..b32611088c82 100644
--- a/drivers/i2c/busses/i2c-aspeed.c
+++ b/drivers/i2c/busses/i2c-aspeed.c
@@ -1588,6 +1588,11 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev)
bus->dev = &pdev->dev;
+ /* Disable bus and clean up any left over interrupt state. */
+ writel(0, bus->base + ASPEED_I2C_FUN_CTRL_REG);
+ writel(0, bus->base + ASPEED_I2C_INTR_CTRL_REG);
+ writel(0xffffffff, bus->base + ASPEED_I2C_INTR_STS_REG);
+
parent_clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(parent_clk))
return PTR_ERR(parent_clk);
@@ -1630,17 +1635,6 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev)
strlcpy(bus->adap.name, pdev->name, sizeof(bus->adap.name));
i2c_set_adapdata(&bus->adap, bus);
- /* Clean up any left over interrupt state. */
- writel(0, bus->base + ASPEED_I2C_INTR_CTRL_REG);
- writel(0xffffffff, bus->base + ASPEED_I2C_INTR_STS_REG);
- /*
- * bus.lock does not need to be held because the interrupt handler has
- * not been enabled yet.
- */
- ret = aspeed_i2c_init(bus, pdev);
- if (ret < 0)
- goto out_free_dma_buf;
-
irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
ret = devm_request_irq(&pdev->dev, irq, aspeed_i2c_bus_irq,
0, dev_name(&pdev->dev), bus);
@@ -1653,6 +1647,10 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev)
platform_set_drvdata(pdev, bus);
+ ret = aspeed_i2c_init(bus, pdev);
+ if (ret < 0)
+ goto out_free_dma_buf;
+
dev_info(bus->dev, "i2c bus %d registered (%s mode), irq %d\n",
bus->adap.nr, bus->dma_buf ? "dma" :
bus->buf_base ? "buffer" : "byte",
--
2.7.4
|