diff options
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0075-Refine-initialization-flow-in-I2C-driver.patch')
-rw-r--r-- | meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0075-Refine-initialization-flow-in-I2C-driver.patch | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0075-Refine-initialization-flow-in-I2C-driver.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0075-Refine-initialization-flow-in-I2C-driver.patch new file mode 100644 index 000000000..52c3617d6 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0075-Refine-initialization-flow-in-I2C-driver.patch @@ -0,0 +1,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 + |