From nobody Tue Dec 16 16:37:30 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1AC7FEE49B5 for ; Wed, 23 Aug 2023 16:10:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235792AbjHWQKY (ORCPT ); Wed, 23 Aug 2023 12:10:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46332 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234317AbjHWQKV (ORCPT ); Wed, 23 Aug 2023 12:10:21 -0400 Received: from mail-pl1-x632.google.com (mail-pl1-x632.google.com [IPv6:2607:f8b0:4864:20::632]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C15E3E7A; Wed, 23 Aug 2023 09:10:17 -0700 (PDT) Received: by mail-pl1-x632.google.com with SMTP id d9443c01a7336-1bf1935f6c2so39520645ad.1; Wed, 23 Aug 2023 09:10:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1692807017; x=1693411817; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=Z0xBOCTk1h2aY6GHi56izPP9ZKIEziL2gPlL/YE4i+4=; b=ipPWfyUNYuRmPTdTq7hZyx0FMVwjxEbwcsNALJwZeA+hPyS3Qult+/I0vjW5WDHUPz N0qybclfWYHirwhZ+wYIgu1FagJJGOpEVByAsc1JyNO/kvtjeNJ5xza9yXrpBndEbFU3 dMzVqp4Zf+Puo6w/uVBPtsu8iRn0yPWvZ8cVTn5tM0R0H8cy+B3dJe2t2shQRBwyDscC Q+QrYF+PDG5L8ruj6AOfTA5c8U9ksbd9Xm1Lb4+Sob5XnLl2t+l4NBfQm4vztxTyRSvN 36riPFJE3siMTO7GqrRfUT1fi7XNARnuberLmGHItM0ihzYKCLLbsgy+zuFib0iRbw8W r7dw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692807017; x=1693411817; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=Z0xBOCTk1h2aY6GHi56izPP9ZKIEziL2gPlL/YE4i+4=; b=cd8LJHbIDe3BB0n/8hFz7LqeCozOr68AcxUZvVZHrq4keM1/rODDjWjxEVtx6zgwB9 dDizcU42VsjdBEzHa6GKNAMUqejgp2B+h1BiJ+7u+ujaMhKn1Mx4tQngxTyhdr8xhWRL p5cE9vQh1kWRGYtNzlf0uB1Rm3kop6cTOZZcimcQn9G0zKOd6dygicdpbhlRbloIRZqJ 4TeDFEPjxw4ec/hUdudld8ItTpX3qN184XdDWotcQEmZCBPfszZuY7/H9whAmNuq3Uub f1+LaNSNH4wwxhrDsQytREj9bYVd89lZ9votdHDR1OeMIAGhspJfUlxYpZVZqS/B4C9o opZA== X-Gm-Message-State: AOJu0YySXvTNq3Ou2EsPS0tj5NUD2QlNguh36CsuWjo087zcTDjlpzNM odZnS5w+aiLlGO1ULff8ubLp/dc4exDd4xPH X-Google-Smtp-Source: AGHT+IEACi22azJ0gb7FjH9uYx64mg3/D5Ji14qErxd0e2/DACqtz/r6g9qNG75rGfKjuX3cNDSlJQ== X-Received: by 2002:a17:903:1c4:b0:1b5:522a:1578 with SMTP id e4-20020a17090301c400b001b5522a1578mr19098503plh.29.1692807017054; Wed, 23 Aug 2023 09:10:17 -0700 (PDT) Received: from peter-bmc.dhcpserver.bu9bmc.local (1-34-21-66.hinet-ip.hinet.net. [1.34.21.66]) by smtp.gmail.com with ESMTPSA id 19-20020a170902c11300b001afd821c057sm11238296pli.58.2023.08.23.09.10.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 09:10:16 -0700 (PDT) From: peteryin To: joel@jms.id.au, andrew@aj.id.au, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, eajames@linux.ibm.com, johnny_huang@aspeedtech.com, linux-arm-kernel@lists.infradead.org, linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Cc: peteryin , peteryin Subject: [PATCH] Title: Select GPIO command source. Date: Thu, 24 Aug 2023 00:08:10 +0800 Message-Id: <20230823160810.1067102-1-peteryin.openbmc@gmail.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: peteryin Description: The capability to choose the GPIO command source between ARM LPC and Coprocessor CPU is supported. Test Plan: Get Bank gpio command source e.g. cd /sys/bus/platform/drivers/aspeed-command-source/ cat 1e780000.gpio-command-source/bank_abcd ARM ARM ARM ARM Set Bank gpio command source. e.g. cd /sys/bus/platform/drivers/aspeed-command-source/ echo "A ARM" > 1e780000.gpio-command-source/bank_abcd or echo "A LPC" > 1e780000.gpio-command-source/bank_abcd or$ echo "A COP" > 1e780000.gpio-command-source/bank_abcd Signed-off-by: peteryin --- .../sysfs-driver-aspeed-gpio-command-source | 24 ++ .../soc/aspeed/gpio-command-source.yaml | 58 ++++ drivers/soc/aspeed/Kconfig | 9 + drivers/soc/aspeed/Makefile | 1 + drivers/soc/aspeed/aspeed-command-source.c | 266 ++++++++++++++++++ 5 files changed, 358 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-driver-aspeed-gpio-comm= and-source create mode 100644 Documentation/devicetree/bindings/soc/aspeed/gpio-comma= nd-source.yaml create mode 100644 drivers/soc/aspeed/aspeed-command-source.c diff --git a/Documentation/ABI/testing/sysfs-driver-aspeed-gpio-command-sou= rce b/Documentation/ABI/testing/sysfs-driver-aspeed-gpio-command-source new file mode 100644 index 000000000000..4698f47a1f75 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-aspeed-gpio-command-source @@ -0,0 +1,24 @@ +What: /sys/bus/platform/drivers/aspeed-command-source/\*command\*/bank\* +Date: August 2023 +Contact: Peter Yin +Description: Get or set the gpio command source for ARM, LPC or Coprocesso= r CPU. + + When read, each file shows the list of available options with bank + that depends on the selected bank file. + + e.g. + get gpio command source + cd /sys/bus/platform/drivers/aspeed-command-source/ + cat 1e780000.gpio-command-source/bank_abcd + ARM ARM ARM ARM + In this case, gets bank gpio command source. + + + e.g. + set gpio command source + cd /sys/bus/platform/drivers/aspeed-command-source/ + echo "A ARM" > 1e780000.gpio-command-source/bank_abcd + or + echo "A LPC" > 1e780000.gpio-command-source/bank_abcd + or + echo "A COP" > 1e780000.gpio-command-source/bank_abcd diff --git a/Documentation/devicetree/bindings/soc/aspeed/gpio-command-sour= ce.yaml b/Documentation/devicetree/bindings/soc/aspeed/gpio-command-source.= yaml new file mode 100644 index 000000000000..034183667501 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/aspeed/gpio-command-source.yaml @@ -0,0 +1,58 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# # Copyright (c) 2023 Quanta Inc. +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/soc/aspeed/gpio-command-source.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Aspeed UART Routing Controller + +maintainers: + - Peter Yin + +description: + The Aspeed gpio command source control allow to dynamically write the in= puts for + the built-in gpio command source. + + This allows, for example, to connect the gpio command source to ARM LPC = or Coprocessor CPU. + e.g. let LPC port80 to connect the gpio group. + + This driver is for the BMC side. The sysfs files allow the BMC userspace + which owns the system configuration policy, to configure gpio command so= urce. + +properties: + compatible: + items: + - enum: + - aspeed,ast2600-gpio-command-source + reg: + maxItems: 1 + +required: + - compatible + +additionalProperties: false + +examples: + - | + gpio0: gpio@1e780000 { + #gpio-cells =3D <2>; + gpio-controller; + compatible =3D "aspeed,ast2600-gpio", "simple-mfd", "syscon"; + reg =3D <0x1e780000 0x400>; + interrupts =3D ; + gpio-ranges =3D <&pinctrl 0 0 208>; + ngpios =3D <208>; + clocks =3D <&syscon ASPEED_CLK_APB2>; + interrupt-controller; + #interrupt-cells =3D <2>; + + #address-cells =3D <1>; + #size-cells =3D <1>; + ranges =3D <0x0 0x1e780000 0x400>; + gpio_command_source: gpio-command-source@0 { + compatible =3D "aspeed,ast2600-gpio-command-source"; + reg =3D <0x0 0x400>; + status =3D "disabled"; + }; + }; diff --git a/drivers/soc/aspeed/Kconfig b/drivers/soc/aspeed/Kconfig index bdea4b0a687b..066bea90bd00 100644 --- a/drivers/soc/aspeed/Kconfig +++ b/drivers/soc/aspeed/Kconfig @@ -34,6 +34,15 @@ config ASPEED_UART_ROUTING users to perform runtime configuration of the RX muxes among the UART controllers and I/O pins. =20 +config ASPEED_COMMAND_SOURCE + tristate "ASPEED gpio command source control" + select REGMAP + select MFD_SYSCON + default ARCH_ASPEED + help + Provides a driver to control the gpio command source to ARM, + LPC or Coprocessor. + config ASPEED_P2A_CTRL tristate "ASPEED P2A (VGA MMIO to BMC) bridge control" select REGMAP diff --git a/drivers/soc/aspeed/Makefile b/drivers/soc/aspeed/Makefile index 224127a1dd55..3246f41fe2b2 100644 --- a/drivers/soc/aspeed/Makefile +++ b/drivers/soc/aspeed/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_ASPEED_LPC_CTRL) +=3D aspeed-lpc-ctrl.o obj-$(CONFIG_ASPEED_LPC_SNOOP) +=3D aspeed-lpc-snoop.o obj-$(CONFIG_ASPEED_UART_ROUTING) +=3D aspeed-uart-routing.o +obj-$(CONFIG_ASPEED_COMMAND_SOURCE) +=3D aspeed-command-source.o obj-$(CONFIG_ASPEED_P2A_CTRL) +=3D aspeed-p2a-ctrl.o obj-$(CONFIG_ASPEED_SOCINFO) +=3D aspeed-socinfo.o obj-$(CONFIG_ASPEED_SBC) +=3D aspeed-sbc.o diff --git a/drivers/soc/aspeed/aspeed-command-source.c b/drivers/soc/aspee= d/aspeed-command-source.c new file mode 100644 index 000000000000..ecf15b56c1a6 --- /dev/null +++ b/drivers/soc/aspeed/aspeed-command-source.c @@ -0,0 +1,266 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2023 Quanta Inc. + */ +#include +#include +#include +#include +#include +#include +#include + +/* register offsets */ +#define GPIO60 0x60 +#define GPIO68 0x68 +#define GPIO90 0x90 +#define GPIOE0 0xE0 +#define GPIO110 0x110 +#define GPIO140 0x140 +#define GPIO170 0x170 + +/* attributes options */ +#define GPIO_COMMAND_SOURCE_ABCD "bank_abcd" +#define GPIO_COMMAND_SOURCE_EFGH "bank_efgh" +#define GPIO_COMMAND_SOURCE_IJKL "bank_ijkl" +#define GPIO_COMMAND_SOURCE_MNOP "bank_mnop" +#define GPIO_COMMAND_SOURCE_QRST "bank_qrst" +#define GPIO_COMMAND_SOURCE_UVWX "bank_uvwx" +#define GPIO_COMMAND_SOURCE_YZ "bank_yz" +#define GPIO_BANK_SIZE (4) + +#define COMMAND_SOURCE1_OFFSET (4) +#define GPIO_GPIO_GRUOP_OFFSET (8) + +struct aspeed_gpio_command_source { + struct regmap *map; + struct attribute_group const *attr_grp; +}; + +struct aspeed_gpio_command_source_selector { + struct device_attribute dev_attr; + uint32_t reg; + const char *const group[]; +}; + +static const char *const options[] =3D { + "ARM", "LPC", "COP", "NON", NULL +}; + + +#define to_routing_selector(_dev_attr) \ + container_of(_dev_attr, struct aspeed_gpio_command_source_selector, dev_a= ttr) + +static ssize_t aspeed_gpio_command_source_show(struct device *dev, + struct device_attribute *attr, + char *buf); + +static ssize_t aspeed_gpio_command_source_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); + +#define ROUTING_ATTR(_name) { \ + .attr =3D {.name =3D _name, \ + .mode =3D VERIFY_OCTAL_PERMISSIONS(0644) }, \ + .show =3D aspeed_gpio_command_source_show, \ + .store =3D aspeed_gpio_command_source_store, \ +} + +/* routing selector for AST26xx */ +static struct aspeed_gpio_command_source_selector ast2600_bank_abcd =3D { + .dev_attr =3D ROUTING_ATTR(GPIO_COMMAND_SOURCE_ABCD), + .reg =3D GPIO60, + .group =3D { "A", "B", "C", "D", NULL}, +}; + +static struct aspeed_gpio_command_source_selector ast2600_bank_efgh =3D { + .dev_attr =3D ROUTING_ATTR(GPIO_COMMAND_SOURCE_EFGH), + .reg =3D GPIO68, + .group =3D { "E", "F", "G", "H", NULL}, + +}; + +static struct aspeed_gpio_command_source_selector ast2600_bank_ijkl =3D { + .dev_attr =3D ROUTING_ATTR(GPIO_COMMAND_SOURCE_IJKL), + .reg =3D GPIO90, + .group =3D { "I", "J", "L", "L", NULL}, +}; + +static struct aspeed_gpio_command_source_selector ast2600_bank_mnop =3D { + .dev_attr =3D ROUTING_ATTR(GPIO_COMMAND_SOURCE_MNOP), + .reg =3D GPIOE0, + .group =3D { "M", "N", "O", "P", NULL}, +}; + +static struct aspeed_gpio_command_source_selector ast2600_bank_qrst =3D { + .dev_attr =3D ROUTING_ATTR(GPIO_COMMAND_SOURCE_QRST), + .reg =3D GPIO110, + .group =3D { "Q", "R", "S", "T", NULL}, +}; + +static struct aspeed_gpio_command_source_selector ast2600_bank_uvwx =3D { + .dev_attr =3D ROUTING_ATTR(GPIO_COMMAND_SOURCE_UVWX), + .reg =3D GPIO140, + .group =3D { "U", "V", "W", "X", NULL}, +}; + +static struct aspeed_gpio_command_source_selector ast2600_bank_yz =3D { + .dev_attr =3D ROUTING_ATTR(GPIO_COMMAND_SOURCE_YZ), + .reg =3D GPIO170, + .group =3D { "Y", "Z", NULL, NULL, NULL}, +}; + +static struct attribute *ast2600_gpio_command_source_attrs[] =3D { + &ast2600_bank_abcd.dev_attr.attr, + &ast2600_bank_efgh.dev_attr.attr, + &ast2600_bank_ijkl.dev_attr.attr, + &ast2600_bank_mnop.dev_attr.attr, + &ast2600_bank_qrst.dev_attr.attr, + &ast2600_bank_uvwx.dev_attr.attr, + &ast2600_bank_yz.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ast2600_gpio_command_source_attr_group= =3D { + .attrs =3D ast2600_gpio_command_source_attrs, +}; + +static ssize_t aspeed_gpio_command_source_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct aspeed_gpio_command_source *gpio_cmd_src =3D dev_get_drvdata(dev); + struct aspeed_gpio_command_source_selector *sel =3D to_routing_selector(a= ttr); + uint8_t cmd_src0, cmd_src1; + uint32_t val1 =3D 0, val2 =3D 0; + int len =3D 0; + + regmap_read(gpio_cmd_src->map, sel->reg, &val1); + regmap_read(gpio_cmd_src->map, sel->reg + GPIO_GPIO_GRUOP_OFFSET, &val2); + + for (int i =3D 0; i < GPIO_BANK_SIZE; i++) { + cmd_src0 =3D (uint8_t)(val1 >> i*8); + cmd_src1 =3D (uint8_t)(val2 >> i*8); + + if (cmd_src0 =3D=3D 0 && cmd_src1 =3D=3D 0) + len +=3D sysfs_emit_at(buf, len, "%s ", options[0]); + else if (cmd_src0 =3D=3D 1 && cmd_src1 =3D=3D 0) + len +=3D sysfs_emit_at(buf, len, "%s ", options[1]); + else if (cmd_src0 =3D=3D 0 && cmd_src1 =3D=3D 1) + len +=3D sysfs_emit_at(buf, len, "%s ", options[2]); + else if (cmd_src0 =3D=3D 1 && cmd_src1 =3D=3D 1) + len +=3D sysfs_emit_at(buf, len, "%s ", options[3]); + } + + len +=3D sysfs_emit_at(buf, len, "\n"); + return len; +} + +static ssize_t aspeed_gpio_command_source_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aspeed_gpio_command_source *gpio_cmd_src =3D dev_get_drvdata(dev); + struct aspeed_gpio_command_source_selector *sel =3D to_routing_selector(a= ttr); + + char input1[4], input2[4]; + int idx1 =3D -1, idx2 =3D -1; + uint8_t cmd_src0 =3D 0, cmd_src1 =3D 0; + + if (count >=3D sizeof(input1) + sizeof(input2)) + return -EINVAL; // Input is too long + + if (sscanf(buf, "%3s %3s", input1, input2) !=3D 2) + return -EINVAL; // Failed to parse input + + idx1 =3D match_string(sel->group, -1, input1); //match gpio group + idx2 =3D match_string(options, -1, input2); //match action + if (idx1 < 0 || idx2 < 0) { + dev_err(dev, "invalid value idx1=3D%d,idx2=3D%d\n", idx1, idx2); + return -EINVAL; + } + + if (idx2 =3D=3D 0) { //ARM + cmd_src0 =3D 0; + cmd_src1 =3D 0; + } else if (idx2 =3D=3D 1) { //LPC + cmd_src0 =3D 1; + cmd_src1 =3D 0; + } else if (idx2 =3D=3D 2) { //Coprocessor CPU + cmd_src0 =3D 0; + cmd_src1 =3D 1; + } else if (idx2 =3D=3D 3) { //Reserve + cmd_src0 =3D 1; + cmd_src1 =3D 1; + } + + regmap_update_bits(gpio_cmd_src->map, + sel->reg, + 1 << (idx1*GPIO_GPIO_GRUOP_OFFSET), + cmd_src0 << (idx1 * GPIO_GPIO_GRUOP_OFFSET)); + + regmap_update_bits(gpio_cmd_src->map, + (sel->reg) + COMMAND_SOURCE1_OFFSET, + 1 << (idx1*GPIO_GPIO_GRUOP_OFFSET), + cmd_src1 << (idx1 * GPIO_GPIO_GRUOP_OFFSET)); + return count; +} + +static int aspeed_gpio_command_source_probe(struct platform_device *pdev) +{ + int rc; + struct device *dev =3D &pdev->dev; + struct aspeed_gpio_command_source *gpio_cmd_src; + + gpio_cmd_src =3D devm_kzalloc(&pdev->dev, sizeof(*gpio_cmd_src), GFP_KERN= EL); + if (!gpio_cmd_src) + return -ENOMEM; + + gpio_cmd_src->map =3D syscon_node_to_regmap(dev->parent->of_node); + if (IS_ERR(gpio_cmd_src->map)) { + dev_err(dev, "cannot get regmap\n"); + return PTR_ERR(gpio_cmd_src->map); + } + + gpio_cmd_src->attr_grp =3D of_device_get_match_data(dev); + + rc =3D sysfs_create_group(&dev->kobj, gpio_cmd_src->attr_grp); + if (rc < 0) + return rc; + + dev_set_drvdata(dev, gpio_cmd_src); + dev_info(dev, "module probe success\n"); + + return 0; +} + +static int aspeed_gpio_command_source_remove(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct aspeed_gpio_command_source *gpio_cmd_src =3D platform_get_drvdata(= pdev); + + sysfs_remove_group(&dev->kobj, gpio_cmd_src->attr_grp); + + return 0; +} + +static const struct of_device_id aspeed_gpio_command_source_table[] =3D { + { .compatible =3D "aspeed,ast2600-gpio-command-source", + .data =3D &ast2600_gpio_command_source_attr_group }, + { }, +}; + +static struct platform_driver aspeed_gpio_command_source_driver =3D { + .driver =3D { + .name =3D "aspeed-gpio-command-source", + .of_match_table =3D aspeed_gpio_command_source_table, + }, + .probe =3D aspeed_gpio_command_source_probe, + .remove =3D aspeed_gpio_command_source_remove, +}; + +module_platform_driver(aspeed_gpio_command_source_driver); + +MODULE_AUTHOR("Peter Yin "); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Driver to configure Aspeed GPIO Command Source"); --=20 2.25.1