From patchwork Tue Sep 15 18:45:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zev Weiss X-Patchwork-Id: 11777569 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9CB4C618 for ; Tue, 15 Sep 2020 18:49:08 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6993B20735 for ; Tue, 15 Sep 2020 18:49:08 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="PuXyDM9s"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=bewilderbeest.net header.i=@bewilderbeest.net header.b="IshQ+GAr" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6993B20735 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=bewilderbeest.net Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:To:From: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Owner; bh=T0Q/BdVo9k6tO1r2qpkDR4Tl2ctJgFChTaoKmhuogX4=; b=PuXyDM9sc3Xj4kdf/N6cjs/U8l tmzByiIuQNUrcCW8eW7wrw2xDaOnBzz8Zpt71/2vfXIKHGje0jn17q843W7P1/jyRNTLcBB8cvcS+ kjv/pkyRjalWVFYQaYXjVvJf23KYamDioYecUg6Eoe4y6U7+hV3Qr9HYTv931FiNdQYUpCKryOeoX jO3GZlO+nv6I0XF9MQsoAL96NFuYBevWvcZs+rG20tDwAIOMud1q/W4JxEufOJSoDRMdSKLZrw2r5 YOsgTxle48VQ70z0U6LksgeQYG5rsdFtWfHrPlQxg5smnPsT/y8s+winM7Kh64CaQu4JND/9T7Hn+ GWe6qKZg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kIFyy-0004Y1-KH; Tue, 15 Sep 2020 18:47:12 +0000 Received: from thorn.bewilderbeest.net ([2605:2700:0:5::4713:9cab]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kIFyv-0004XT-Oy for linux-arm-kernel@lists.infradead.org; Tue, 15 Sep 2020 18:47:11 +0000 Received: from hatter.bewilderbeest.net (unknown [IPv6:2600:6c44:7f:ba20::7c6]) (using TLSv1.2 with cipher DHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: zev) by thorn.bewilderbeest.net (Postfix) with ESMTPSA id 0C4B3806F7; Tue, 15 Sep 2020 11:47:00 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 thorn.bewilderbeest.net 0C4B3806F7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bewilderbeest.net; s=thorn; t=1600195621; bh=FJZOAN5p863bC4FM+I+qvDnKOPec7IEYDsPnpusvWKU=; h=From:To:Cc:Subject:Date:From; b=IshQ+GArRiw/dXPoWZQdc4tiy1LTt+uLkEQtzhFjgCKnZ0MD88YHEgo7DlosaSYWL efk5DOCxDBtnSPOPxgv8LC8rhx+6sVJxOiWwDcbqrVLsp2xaKJu+JkNup+D8Wdtk+y Ur8dkOjEgjj+VCI5ESwH8o8I0hvWXA/xjKTFys0k= From: Zev Weiss To: Brendan Higgins , Benjamin Herrenschmidt , Joel Stanley , Andrew Jeffery , linux-i2c@vger.kernel.org, openbmc@lists.ozlabs.org, linux-arm-kernel@lists.infradead.org, linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org Subject: [PATCH] i2c: aspeed: disable additional device addresses on ast2[56]xx Date: Tue, 15 Sep 2020 13:45:25 -0500 Message-Id: <20200915184525.29665-1-zev@bewilderbeest.net> X-Mailer: git-send-email 2.28.0 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200915_144710_376072_B3032F34 X-CRM114-Status: GOOD ( 17.52 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Zev Weiss Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org The ast25xx and ast26xx have, respectively, two and three configurable slave device addresses to the ast24xx's one. We only support using one at a time, but the others may come up in an indeterminate state depending on hardware/bootloader behavior, so we need to make sure we disable them so as to avoid ending up with phantom devices on the bus. Signed-off-by: Zev Weiss --- drivers/i2c/busses/i2c-aspeed.c | 50 +++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c index a7be6f24450b..20028a7a9f67 100644 --- a/drivers/i2c/busses/i2c-aspeed.c +++ b/drivers/i2c/busses/i2c-aspeed.c @@ -117,6 +117,8 @@ /* 0x18 : I2CD Slave Device Address Register */ #define ASPEED_I2CD_DEV_ADDR_MASK GENMASK(6, 0) +#define ASPEED_I2CD_DEV_ADDR2_ENABLE BIT(15) +#define ASPEED_I2CD_DEV_ADDR3_ENABLE BIT(23) enum aspeed_i2c_master_state { ASPEED_I2C_MASTER_INACTIVE, @@ -139,6 +141,16 @@ enum aspeed_i2c_slave_state { ASPEED_I2C_SLAVE_STOP, }; +struct aspeed_i2c_model { + u32 (*get_clk_reg_val)(struct device *dev, u32 divisor); + + /* + * Some models support multiple device addresses -- we only support + * using one, but we need to disable the others if they're present. + */ + unsigned int num_device_addrs; +}; + struct aspeed_i2c_bus { struct i2c_adapter adap; struct device *dev; @@ -147,8 +159,7 @@ struct aspeed_i2c_bus { /* Synchronizes I/O mem access to base. */ spinlock_t lock; struct completion cmd_complete; - u32 (*get_clk_reg_val)(struct device *dev, - u32 divisor); + const struct aspeed_i2c_model *model; unsigned long parent_clk_frequency; u32 bus_frequency; /* Transaction state. */ @@ -726,6 +737,13 @@ static void __aspeed_i2c_reg_slave(struct aspeed_i2c_bus *bus, u16 slave_addr) addr_reg_val = readl(bus->base + ASPEED_I2C_DEV_ADDR_REG); addr_reg_val &= ~ASPEED_I2CD_DEV_ADDR_MASK; addr_reg_val |= slave_addr & ASPEED_I2CD_DEV_ADDR_MASK; + + /* Disable additional addresses on hardware that has them. */ + if (bus->model->num_device_addrs > 1) + addr_reg_val &= ~ASPEED_I2CD_DEV_ADDR2_ENABLE; + if (bus->model->num_device_addrs > 2) + addr_reg_val &= ~ASPEED_I2CD_DEV_ADDR3_ENABLE; + writel(addr_reg_val, bus->base + ASPEED_I2C_DEV_ADDR_REG); /* Turn on slave mode. */ @@ -863,6 +881,11 @@ static u32 aspeed_i2c_24xx_get_clk_reg_val(struct device *dev, u32 divisor) return aspeed_i2c_get_clk_reg_val(dev, GENMASK(2, 0), divisor); } +static const struct aspeed_i2c_model aspeed_i2c_24xx_bus = { + .get_clk_reg_val = aspeed_i2c_24xx_get_clk_reg_val, + .num_device_addrs = 1, +}; + static u32 aspeed_i2c_25xx_get_clk_reg_val(struct device *dev, u32 divisor) { /* @@ -872,6 +895,16 @@ static u32 aspeed_i2c_25xx_get_clk_reg_val(struct device *dev, u32 divisor) return aspeed_i2c_get_clk_reg_val(dev, GENMASK(3, 0), divisor); } +static const struct aspeed_i2c_model aspeed_i2c_25xx_bus = { + .get_clk_reg_val = aspeed_i2c_25xx_get_clk_reg_val, + .num_device_addrs = 2, +}; + +static const struct aspeed_i2c_model aspeed_i2c_26xx_bus = { + .get_clk_reg_val = aspeed_i2c_25xx_get_clk_reg_val, + .num_device_addrs = 3, +}; + /* precondition: bus.lock has been acquired. */ static int aspeed_i2c_init_clk(struct aspeed_i2c_bus *bus) { @@ -882,7 +915,7 @@ static int aspeed_i2c_init_clk(struct aspeed_i2c_bus *bus) clk_reg_val &= (ASPEED_I2CD_TIME_TBUF_MASK | ASPEED_I2CD_TIME_THDSTA_MASK | ASPEED_I2CD_TIME_TACST_MASK); - clk_reg_val |= bus->get_clk_reg_val(bus->dev, divisor); + clk_reg_val |= bus->model->get_clk_reg_val(bus->dev, divisor); writel(clk_reg_val, bus->base + ASPEED_I2C_AC_TIMING_REG1); writel(ASPEED_NO_TIMEOUT_CTRL, bus->base + ASPEED_I2C_AC_TIMING_REG2); @@ -946,15 +979,15 @@ static int aspeed_i2c_reset(struct aspeed_i2c_bus *bus) static const struct of_device_id aspeed_i2c_bus_of_table[] = { { .compatible = "aspeed,ast2400-i2c-bus", - .data = aspeed_i2c_24xx_get_clk_reg_val, + .data = &aspeed_i2c_24xx_bus, }, { .compatible = "aspeed,ast2500-i2c-bus", - .data = aspeed_i2c_25xx_get_clk_reg_val, + .data = &aspeed_i2c_25xx_bus, }, { .compatible = "aspeed,ast2600-i2c-bus", - .data = aspeed_i2c_25xx_get_clk_reg_val, + .data = &aspeed_i2c_26xx_bus, }, { }, }; @@ -1002,10 +1035,9 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev) match = of_match_node(aspeed_i2c_bus_of_table, pdev->dev.of_node); if (!match) - bus->get_clk_reg_val = aspeed_i2c_24xx_get_clk_reg_val; + bus->model = &aspeed_i2c_24xx_bus; else - bus->get_clk_reg_val = (u32 (*)(struct device *, u32)) - match->data; + bus->model = match->data; /* Initialize the I2C adapter */ spin_lock_init(&bus->lock);