Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp4552422pxj; Tue, 8 Jun 2021 17:47:10 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwNF2LIJp1FxBZOu32EEQyrE+BpSMes9qg+BiXGZKK67yo7vyRqdZtobfL+/gQawqf6LQJn X-Received: by 2002:a50:99d5:: with SMTP id n21mr28186576edb.223.1623199629972; Tue, 08 Jun 2021 17:47:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1623199629; cv=none; d=google.com; s=arc-20160816; b=mak14hHrRmiJ5V3sxclZropIDy0mwuLbx+jXopxygfHNGZNjuMgIgK+prHi+llDFK7 +0sGLjAp/quJie4VV9nemBtpx/09+fwscGYrdB/L3OsMs2e1z1aJWm56Lv5/eBBQZvDh 2yOJaDhs7GpTwRwC1SXCxegoRCcH+e0vOJo0uJz9pP7VmGFu0uqe90+rzL+EtS5Cj6dH hlavCT6FcVjDGaZ6ScZoIpNEUqfAQsQmGZ5nlIm8QPidNtjSGeKaLLkqxtoVIpm0KMh1 yjnpbxZ+dlnWiYLpuXz9u/tPt1M9xr43dmID0wXwH9Y3RwOkrBavX8DzTNJ7im2XHMy5 zWSA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:dkim-signature; bh=RcW5ROXgyW9XQfhcLFsrjFXYe699upJtdQ4O8F1RtFY=; b=DdD+X478LmkFYkHIJtHVO+qkjmsXsbP5G6dc2wceBzmVmvWBASdGPvowkVvvGKB3QI c3t0Xhh/hLQlG+hYl5iy0dxgWAbC4RB0vAbvDvMf0gMCzyKSetXCcMJxhw0nuQhJ/PM1 Nkk/pApj5D/jYTQbFs0irMtN24WJEZ8SZZo5aaxpJ7KSV7/fhBcdpzvmxJp/h66Zk+qC rHTQU0UuVwW0M+mj99dKXh0sntrYs7A14ohPXjFacsCiImldnft7xH8i06Z5obXGqQyV u4FE0eOL8SHhC4gCDh+zGoS1hAd7X6ZXkVnd9FCAuG+FoDnJKdw3Ikn+IHXn3jzgfp3v 0XcA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@aj.id.au header.s=fm3 header.b=GUODNA1X; dkim=pass header.i=@messagingengine.com header.s=fm3 header.b=qA+mMLSy; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id p8si958159ejc.107.2021.06.08.17.46.46; Tue, 08 Jun 2021 17:47:09 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@aj.id.au header.s=fm3 header.b=GUODNA1X; dkim=pass header.i=@messagingengine.com header.s=fm3 header.b=qA+mMLSy; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231992AbhFHKwN (ORCPT + 99 others); Tue, 8 Jun 2021 06:52:13 -0400 Received: from new4-smtp.messagingengine.com ([66.111.4.230]:34723 "EHLO new4-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232007AbhFHKwH (ORCPT ); Tue, 8 Jun 2021 06:52:07 -0400 Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailnew.nyi.internal (Postfix) with ESMTP id 3FB3458060C; Tue, 8 Jun 2021 06:50:14 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Tue, 08 Jun 2021 06:50:14 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aj.id.au; h=from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm3; bh=RcW5ROXgyW9XQ fhcLFsrjFXYe699upJtdQ4O8F1RtFY=; b=GUODNA1XboZEhWUoLR4bk1tX157bO sb8ufTgQIklqyM8eqKhTKISsyMPZyOMt3fTTMW0l8vlpvVmedxU/FyLCAKZg9GLL WKkb20grDYsXsYvRT9w2gyP+iWr03EX4KTX/OnLfj+yBS+drj74DFJ0lcFdvjs9I KdB9muuuy5XT7qH1G4aaI/6KOtZLeOIQ1s0+M3J3i+HRsH6v1mSk1lU6EhVc+h/p +bEn1eAW3K3mINFos1zQMnDldh2Txbbp3aPdVFbW4NGtMJMm9uAp1TTMJpNcAXa3 s38xR03HUhEzIbRwQxIdLPChNGnXOVWlx/vpaaqOjGQce6bdNvY2Zj3DA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=RcW5ROXgyW9XQfhcLFsrjFXYe699upJtdQ4O8F1RtFY=; b=qA+mMLSy c9ETPb45R/ndNVA6zya4a0UJMLT1n05q/d51L/jsTGO21Ia/ghWHWiF7T8naDHfZ XGyR4NJB5VoMRYveO9UfcEEScwNSWmeSBJBZRQAZHJvPQOHMWjLKoN7Je5suc2Dj WU6Qc84143GHV8oEhDuyzSWXZn/APysY58AWZkuP55az2UDfkKHuoGgwR5m3NM46 adEYgmtp4kAmkxl4m/GIwSsGzj3mo2y2mpZwcGemZCZp8mICn64MSZUdE+x5M3F1 L2QnbdvzBTv6AMQCRtEBPZTKfFIwWOKQyCDlMQpX9lEmavSAQeFYUVkax5UsXjmW +wH6ugsDUHjDEQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledrfedtledgudeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomheptehnughrvgifucflvghffhgvrhihuceorghnughrvgifsegr jhdrihgurdgruheqnecuggftrfgrthhtvghrnhepjefgvdevheetkeevgeegleelgfelte etjeffleffvdduudevieffgeetleevhfetnecuvehluhhsthgvrhfuihiivgepvdenucfr rghrrghmpehmrghilhhfrhhomheprghnughrvgifsegrjhdrihgurdgruh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 8 Jun 2021 06:50:04 -0400 (EDT) From: Andrew Jeffery To: openipmi-developer@lists.sourceforge.net, openbmc@lists.ozlabs.org, minyard@acm.org Cc: devicetree@vger.kernel.org, tmaimon77@gmail.com, linux-aspeed@lists.ozlabs.org, avifishman70@gmail.com, venture@google.com, linux-kernel@vger.kernel.org, tali.perry1@gmail.com, robh+dt@kernel.org, chiawei_wang@aspeedtech.com, linux-arm-kernel@lists.infradead.org, benjaminfair@google.com, arnd@arndb.de, zweiss@equinix.com, joel@jms.id.au, KWLIU@nuvoton.com Subject: [PATCH v4 16/16] ipmi: kcs_bmc_aspeed: Optionally apply status address Date: Tue, 8 Jun 2021 20:17:57 +0930 Message-Id: <20210608104757.582199-17-andrew@aj.id.au> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210608104757.582199-1-andrew@aj.id.au> References: <20210608104757.582199-1-andrew@aj.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Some Aspeed KCS devices can derive the status register address from the address of the data register. As such, the address of the status register can be implicit in the configuration if desired. On the other hand, sometimes address schemes might be requested that are incompatible with the default addressing scheme. Allow these requests where possible if the devicetree specifies the status register address. Signed-off-by: Andrew Jeffery Reviewed-by: Chia-Wei Wang --- drivers/char/ipmi/kcs_bmc_aspeed.c | 116 +++++++++++++++++++++-------- 1 file changed, 83 insertions(+), 33 deletions(-) diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c index 461cb2c9cc7e..0401089f8895 100644 --- a/drivers/char/ipmi/kcs_bmc_aspeed.c +++ b/drivers/char/ipmi/kcs_bmc_aspeed.c @@ -83,6 +83,8 @@ #define LPC_STR2 0x040 #define LPC_STR3 0x044 #define LPC_HICRB 0x100 +#define LPC_HICRB_EN16LADR2 BIT(5) +#define LPC_HICRB_EN16LADR1 BIT(4) #define LPC_HICRB_IBFIE4 BIT(1) #define LPC_HICRB_LPC4E BIT(0) #define LPC_HICRC 0x104 @@ -96,6 +98,11 @@ #define LPC_IDR4 0x114 #define LPC_ODR4 0x118 #define LPC_STR4 0x11C +#define LPC_LSADR12 0x120 +#define LPC_LSADR12_LSADR2_MASK GENMASK(31, 16) +#define LPC_LSADR12_LSADR2_SHIFT 16 +#define LPC_LSADR12_LSADR1_MASK GENMASK(15, 0) +#define LPC_LSADR12_LSADR1_SHIFT 0 #define OBE_POLL_PERIOD (HZ / 2) @@ -123,7 +130,7 @@ struct aspeed_kcs_bmc { struct aspeed_kcs_of_ops { int (*get_channel)(struct platform_device *pdev); - int (*get_io_address)(struct platform_device *pdev); + int (*get_io_address)(struct platform_device *pdev, u32 addrs[2]); }; static inline struct aspeed_kcs_bmc *to_aspeed_kcs_bmc(struct kcs_bmc_device *kcs_bmc) @@ -217,38 +224,64 @@ static void aspeed_kcs_updateb(struct kcs_bmc_device *kcs_bmc, u32 reg, u8 mask, * C. KCS4 * D / C : CA4h / CA5h */ -static void aspeed_kcs_set_address(struct kcs_bmc_device *kcs_bmc, u16 addr) +static int aspeed_kcs_set_address(struct kcs_bmc_device *kcs_bmc, u32 addrs[2], int nr_addrs) { struct aspeed_kcs_bmc *priv = to_aspeed_kcs_bmc(kcs_bmc); - switch (kcs_bmc->channel) { + if (WARN_ON(nr_addrs < 1 || nr_addrs > 2)) + return -EINVAL; + + switch (priv->kcs_bmc.channel) { case 1: - regmap_update_bits(priv->map, LPC_HICR4, - LPC_HICR4_LADR12AS, 0); - regmap_write(priv->map, LPC_LADR12H, addr >> 8); - regmap_write(priv->map, LPC_LADR12L, addr & 0xFF); + regmap_update_bits(priv->map, LPC_HICR4, LPC_HICR4_LADR12AS, 0); + regmap_write(priv->map, LPC_LADR12H, addrs[0] >> 8); + regmap_write(priv->map, LPC_LADR12L, addrs[0] & 0xFF); + if (nr_addrs == 2) { + regmap_update_bits(priv->map, LPC_LSADR12, LPC_LSADR12_LSADR1_MASK, + addrs[1] << LPC_LSADR12_LSADR1_SHIFT); + + regmap_update_bits(priv->map, LPC_HICRB, LPC_HICRB_EN16LADR1, + LPC_HICRB_EN16LADR1); + } break; case 2: - regmap_update_bits(priv->map, LPC_HICR4, - LPC_HICR4_LADR12AS, LPC_HICR4_LADR12AS); - regmap_write(priv->map, LPC_LADR12H, addr >> 8); - regmap_write(priv->map, LPC_LADR12L, addr & 0xFF); + regmap_update_bits(priv->map, LPC_HICR4, LPC_HICR4_LADR12AS, LPC_HICR4_LADR12AS); + regmap_write(priv->map, LPC_LADR12H, addrs[0] >> 8); + regmap_write(priv->map, LPC_LADR12L, addrs[0] & 0xFF); + if (nr_addrs == 2) { + regmap_update_bits(priv->map, LPC_LSADR12, LPC_LSADR12_LSADR2_MASK, + addrs[1] << LPC_LSADR12_LSADR2_SHIFT); + + regmap_update_bits(priv->map, LPC_HICRB, LPC_HICRB_EN16LADR2, + LPC_HICRB_EN16LADR2); + } break; case 3: - regmap_write(priv->map, LPC_LADR3H, addr >> 8); - regmap_write(priv->map, LPC_LADR3L, addr & 0xFF); + if (nr_addrs == 2) { + dev_err(priv->kcs_bmc.dev, + "Channel 3 only supports inferred status IO address\n"); + return -EINVAL; + } + + regmap_write(priv->map, LPC_LADR3H, addrs[0] >> 8); + regmap_write(priv->map, LPC_LADR3L, addrs[0] & 0xFF); break; case 4: - regmap_write(priv->map, LPC_LADR4, ((addr + 1) << 16) | - addr); + if (nr_addrs == 1) + regmap_write(priv->map, LPC_LADR4, ((addrs[0] + 1) << 16) | addrs[0]); + else + regmap_write(priv->map, LPC_LADR4, (addrs[1] << 16) | addrs[0]); + break; default: - break; + return -EINVAL; } + + return 0; } static inline int aspeed_kcs_map_serirq_type(u32 dt_type) @@ -457,18 +490,18 @@ static int aspeed_kcs_of_v1_get_channel(struct platform_device *pdev) return channel; } -static int aspeed_kcs_of_v1_get_io_address(struct platform_device *pdev) +static int +aspeed_kcs_of_v1_get_io_address(struct platform_device *pdev, u32 addrs[2]) { - u32 slave; int rc; - rc = of_property_read_u32(pdev->dev.of_node, "kcs_addr", &slave); - if (rc || slave > 0xffff) { + rc = of_property_read_u32(pdev->dev.of_node, "kcs_addr", addrs); + if (rc || addrs[0] > 0xffff) { dev_err(&pdev->dev, "no valid 'kcs_addr' configured\n"); return -EINVAL; } - return slave; + return 1; } static int aspeed_kcs_of_v2_get_channel(struct platform_device *pdev) @@ -504,18 +537,30 @@ static int aspeed_kcs_of_v2_get_channel(struct platform_device *pdev) return -EINVAL; } -static int aspeed_kcs_of_v2_get_io_address(struct platform_device *pdev) +static int +aspeed_kcs_of_v2_get_io_address(struct platform_device *pdev, u32 addrs[2]) { - uint32_t slave; int rc; - rc = of_property_read_u32(pdev->dev.of_node, "aspeed,lpc-io-reg", &slave); - if (rc || slave > 0xffff) { - dev_err(&pdev->dev, "no valid 'aspeed,lpc-io-reg' configured\n"); + rc = of_property_read_variable_u32_array(pdev->dev.of_node, + "aspeed,lpc-io-reg", + addrs, 1, 2); + if (rc < 0) { + dev_err(&pdev->dev, "No valid 'aspeed,lpc-io-reg' configured\n"); + return rc; + } + + if (addrs[0] > 0xffff) { + dev_err(&pdev->dev, "Invalid data address in 'aspeed,lpc-io-reg'\n"); + return -EINVAL; + } + + if (rc == 2 && addrs[1] > 0xffff) { + dev_err(&pdev->dev, "Invalid status address in 'aspeed,lpc-io-reg'\n"); return -EINVAL; } - return slave; + return rc; } static int aspeed_kcs_probe(struct platform_device *pdev) @@ -524,9 +569,11 @@ static int aspeed_kcs_probe(struct platform_device *pdev) struct kcs_bmc_device *kcs_bmc; struct aspeed_kcs_bmc *priv; struct device_node *np; - int rc, channel, addr; bool have_upstream_irq; u32 upstream_irq[2]; + int rc, channel; + int nr_addrs; + u32 addrs[2]; np = pdev->dev.of_node->parent; if (!of_device_is_compatible(np, "aspeed,ast2400-lpc-v2") && @@ -544,9 +591,9 @@ static int aspeed_kcs_probe(struct platform_device *pdev) if (channel < 0) return channel; - addr = ops->get_io_address(pdev); - if (addr < 0) - return addr; + nr_addrs = ops->get_io_address(pdev, addrs); + if (nr_addrs < 0) + return nr_addrs; np = pdev->dev.of_node; rc = of_property_read_u32_array(np, "aspeed,lpc-interrupts", upstream_irq, 2); @@ -575,7 +622,9 @@ static int aspeed_kcs_probe(struct platform_device *pdev) priv->obe.remove = false; timer_setup(&priv->obe.timer, aspeed_kcs_check_obe, 0); - aspeed_kcs_set_address(kcs_bmc, addr); + rc = aspeed_kcs_set_address(kcs_bmc, addrs, nr_addrs); + if (rc) + return rc; /* Host to BMC IRQ */ rc = aspeed_kcs_config_downstream_irq(kcs_bmc, pdev); @@ -602,7 +651,8 @@ static int aspeed_kcs_probe(struct platform_device *pdev) return rc; } - dev_info(&pdev->dev, "Initialised channel %d at 0x%x\n", kcs_bmc->channel, addr); + dev_info(&pdev->dev, "Initialised channel %d at 0x%x\n", + kcs_bmc->channel, addrs[0]); return 0; } -- 2.30.2