summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0075-Refine-initialization-flow-in-I2C-driver.patch
blob: 52c3617d66cd737b86abe264687d64154005a094 (plain)
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