From patchwork Thu Dec 19 07:17:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yixun Lan X-Patchwork-Id: 13914547 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6AC4CE77184 for ; Thu, 19 Dec 2024 07:18:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:To:In-Reply-To:References:Message-Id: MIME-Version:Subject:Date:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=QADHoioudRnvLHLT9lcLmah8qwnfglosr+HpGS0WW9k=; b=cXpinPC0D8eDMG JiRcmB1pFT3ciU+7QbkLJ3t5ff+81JwYi04bnMC1dvT1xnQtNuPcdUfZCOmd7gqJqggRvjdyZ7hBi S60+pioCsOQWFr8l32xg5h+8dKF0mAHl/byp7mlwdX7pwmtZ4WfevJhlGtIZkW4U7FTtvFJcO1se2 1mX0S4LyYr2WpBxbQJ0DCw91orXtOFhMxsO6hT/0EUbnf7k+qxATMiRlc9vqtQKEvSecy+nfWu1xN 45TmS7tXcktWYrLDxWnL2p0g7++jYUk0+lLsYb3pxD8xuITjkr4ykNNweonHe1tNGhrMJgm/GebVf /lyjJ1LAkUKkSQ/mEeog==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tOAns-000000013dn-3Yfc; Thu, 19 Dec 2024 07:18:36 +0000 Received: from woodpecker.gentoo.org ([140.211.166.183] helo=smtp.gentoo.org) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tOAnp-000000013cy-3dVg for linux-riscv@lists.infradead.org; Thu, 19 Dec 2024 07:18:35 +0000 From: Yixun Lan Date: Thu, 19 Dec 2024 15:17:43 +0800 Subject: [PATCH v2 1/3] dt-bindings: gpio: spacemit: add support for K1 SoC MIME-Version: 1.0 Message-Id: <20241219-03-k1-gpio-v2-1-28444fd221cd@gentoo.org> References: <20241219-03-k1-gpio-v2-0-28444fd221cd@gentoo.org> In-Reply-To: <20241219-03-k1-gpio-v2-0-28444fd221cd@gentoo.org> To: Linus Walleij , Bartosz Golaszewski , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Conor Dooley , Paul Walmsley , Palmer Dabbelt X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2679; i=dlan@gentoo.org; h=from:subject:message-id; bh=PuvMbdDrX5Trb+pDXq7PJAmUp0RoHA9vJ85lsUKDFM4=; b=owEBzQIy/ZANAwAKATGq6kdZTbvtAcsmYgBnY8ixu0mGraLvHA7T/MWmc4IEZlzlnnzDPK2CQ wuMVJtmSVaJApMEAAEKAH0WIQS1urjJwxtxFWcCI9wxqupHWU277QUCZ2PIsV8UgAAAAAAuAChp c3N1ZXItZnByQG5vdGF0aW9ucy5vcGVucGdwLmZpZnRoaG9yc2VtYW4ubmV0QjVCQUI4QzlDMzF CNzExNTY3MDIyM0RDMzFBQUVBNDc1OTREQkJFRAAKCRAxqupHWU277X/3D/99Rw1E/QBAOgCvsh nASBxGHryoj95OL1ThOJCzsUvYoJ4BCpuN823Stpjx95NeFef0zxiSC4c/UkvjQweTWlKMgkm/W SK6Im4M8C3QeqNT3NRfxKcYPU3cqhR4aWcxKkm813C8YZTAQ7nTpRbQEB6y56DLUp3sJDYusGyR OcoJmzJhnyseUdMk+ZKAPzM2Ff2BP7kDJc26EEduPqckjKLJN8ole/0y0FzS26lvSjQr/UtS3i5 7oxOr7J5/kpML33V5TsHuNrunl7pyACiFwJIvTtFEppHKWhHRd/stjwzby6m5RklvydQzoZU96p pxQc4U3H0xSckgH1YOxjefK5q37iaa41IMrpKdfIokYXUWOsQGyz9VJFBidGsjiJCPi+KVEult7 XA1SNB5SZFoG1LdK/yWTLJc/qv1v77Ws03PvBwyoFjGzHBE2T5HKFI98JD9OwlvMCie59ZDqM7z TPHDrwhDhwLD+BAOClzjfXps7qMzLtB8QdkATk8pXT6LBkJxWFsl1FJ1hbfzWK1OheLO+6knYaT E3OL+2UwnffK9BYaFZFwMNc73qeyKxXaRAc0kSj6mqJMMIFbM8qbFLypNDAsswwzjqe7WYqoOO/ h4x5V3dd/mBDCntZC0t7VIL45+dFe+Vd6PiIVISZe+lqcp5hFG3WcOTnYXXt7G7U3Tzw== X-Developer-Key: i=dlan@gentoo.org; a=openpgp; fpr=50B03A1A5CBCD33576EF8CD7920C0DBCAABEFD55 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20241218_231833_937830_C181EBF8 X-CRM114-Status: GOOD ( 12.61 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, Yixun Lan , Meng Zhang , linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Jesse Taube , Yangyu Chen , Inochi Amaoto , Jisheng Zhang , Meng Zhang , linux-riscv@lists.infradead.org Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org The GPIO controller of K1 support basic functions as input/output, all pins can be used as interrupt which route to one IRQ line, trigger type can be select between rising edge, failing edge, or both. There are four GPIO banks, each consisting of 32 pins. Signed-off-by: Yixun Lan --- .../devicetree/bindings/gpio/spacemit,k1-gpio.yaml | 75 ++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/Documentation/devicetree/bindings/gpio/spacemit,k1-gpio.yaml b/Documentation/devicetree/bindings/gpio/spacemit,k1-gpio.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3d3d0b3bf2c144ed57b717bee50064949e26f087 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/spacemit,k1-gpio.yaml @@ -0,0 +1,75 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/gpio/spacemit,k1-gpio.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: SpacemiT K1 GPIO controller + +maintainers: + - Yixun Lan + +description: + The controller's registers are organized as sets of eight 32-bit + registers with each set controlling a bank of up to 32 pins. A single + interrupt is shared for all of the banks handled by the controller. + +properties: + compatible: + const: spacemit,k1-gpio + + reg: + maxItems: 1 + + ranges: true + + "#gpio-cells": + const: 2 + + gpio-controller: true + + gpio-ranges: true + + interrupts: + maxItems: 1 + description: + The interrupt shared by all GPIO lines for this controller. + + interrupt-names: true + + "#interrupt-cells": + const: 2 + description: + The first cell is the GPIO number, the second should specify interrupt + flag. The controller does not support level interrupts, flags of + IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_LOW should not be used. + Refer for valid flags. + + interrupt-controller: true + +required: + - compatible + - reg + - gpio-controller + - "#gpio-cells" + - interrupts + - interrupt-names + - interrupt-controller + - "#interrupt-cells" + +additionalProperties: false + +examples: + - | + gpio@d4019000 { + compatible = "spacemit,k1-gpio"; + reg = <0xd4019000 0x800>; + gpio-controller; + #gpio-cells = <2>; + interrupts = <58>; + interrupt-names = "gpio_mux"; + interrupt-parent = <&plic>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&pinctrl 0 0 128>; + }; From patchwork Thu Dec 19 07:17:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yixun Lan X-Patchwork-Id: 13914548 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C23E0E7718A for ; Thu, 19 Dec 2024 07:18:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:To:In-Reply-To:References:Message-Id: MIME-Version:Subject:Date:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=F7vwobg80BWMVGlPK3rbculis6w6maSmemSIx8QT7vY=; b=D65KberL66CXjj pLTkbJMsDaGhfwYuTqCN25r7cu973OUALZsIbYku/r6RxPvwVl17t5kZ4Ht77NEBsqrYMuaX2il9h nCICa1Ue2Wibl6FrKs6wvnBmqjTSaW8YkjW1jB470FE9dv67rVecGz6rIkg6nGEO695YzE2iKOVWH ZB5qp7RwjX2+PKGgAs0/sVb8Lc3tua7V+riIGCiqSW7iUC26k4xT+b56IZC8NiRSmDcDcaF0xILyf UJmcaKjj0VxD3GS3IsaCDQh0Uz9ov7pX2yMUIUL+oj+VHHF7nRERhHVMVFxiQbKW4cR7mimIUJufo yt0kjzE8b0Gw0PYosIuQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tOAnz-000000013fF-1gbc; Thu, 19 Dec 2024 07:18:43 +0000 Received: from dev.gentoo.org ([2001:470:ea4a:1:5054:ff:fec7:86e4] helo=smtp.gentoo.org) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tOAnx-000000013eI-0YL1 for linux-riscv@lists.infradead.org; Thu, 19 Dec 2024 07:18:42 +0000 From: Yixun Lan Date: Thu, 19 Dec 2024 15:17:44 +0800 Subject: [PATCH v2 2/3] gpio: spacemit: add support for K1 SoC MIME-Version: 1.0 Message-Id: <20241219-03-k1-gpio-v2-2-28444fd221cd@gentoo.org> References: <20241219-03-k1-gpio-v2-0-28444fd221cd@gentoo.org> In-Reply-To: <20241219-03-k1-gpio-v2-0-28444fd221cd@gentoo.org> To: Linus Walleij , Bartosz Golaszewski , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Conor Dooley , Paul Walmsley , Palmer Dabbelt X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=14101; i=dlan@gentoo.org; h=from:subject:message-id; bh=YBlD3ap+tYhhbw3zxlfrohTkKXocIeXZeG9UPTUClY4=; b=owEBzQIy/ZANAwAKATGq6kdZTbvtAcsmYgBnY8i0b1E1V8JkamVURpaowHQR9FDOCn+Bt+w9D UbFuk02lpOJApMEAAEKAH0WIQS1urjJwxtxFWcCI9wxqupHWU277QUCZ2PItF8UgAAAAAAuAChp c3N1ZXItZnByQG5vdGF0aW9ucy5vcGVucGdwLmZpZnRoaG9yc2VtYW4ubmV0QjVCQUI4QzlDMzF CNzExNTY3MDIyM0RDMzFBQUVBNDc1OTREQkJFRAAKCRAxqupHWU277ZGAEACIykEw9NwTBrDnrj RjH9TOxTSGO2HTV0vh0+35TzJrlu4dmzdkqI2FByai5XGeXPUtu4bVxnT6YpD6pX0TRcfr42imG dG3idyCP17wDaw1FZgeGCdBde7009Bxq8Pxd/XlnhghwPMMQVU10o5EMkxUaWDW0Fho+vQdFSJ5 TCwGimVOLQl0I4Lz+rc5YUPumIye6KtcFDtKxHoAUKJP04BerkJh8NOliWy+/mH+c/+ojbzIJ6j gmThWBvYdWl+u9LUFJKe2gEXpd5ipa4kCIYPYRq4m2WL8aWkEpykMq42lOY++zJ1VDa5CS58anO AhVTrgqrt9HX7LajTZRDYCX6GfOl4AlCZuJS22l9XMsshWirRtDdC2cQRPMvX5WXAy7FpoFhJlf uA90tgWhcRgYke1Hi3xOEqYU2aR3WlrMiaRzXN/YTqGq1wUy+um/oXlEb8/AWfJAEfeoI7OAsKp Dl5pJS6Tx0//DGhqYGjHDWE+mRfW2nc9CHixgcUP4poAO9vbAos9rjo6CObm4V95jDKngLada91 Q345n7KXqsMo2Yc4loZJ4n6uOFLn0EfBIXo2u2g3Tt6crXHf1aJG3A47izyqVy/dTNQeUmZLJyZ QNu2aU5Xs6uKwhf1HqQL6nJfr/7pBsjjLbPt9NuQivP9TJ86dPQO/NIvbnog+FNt/Mqw== X-Developer-Key: i=dlan@gentoo.org; a=openpgp; fpr=50B03A1A5CBCD33576EF8CD7920C0DBCAABEFD55 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20241218_231841_217600_B54FD2AB X-CRM114-Status: GOOD ( 22.63 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, Yixun Lan , Meng Zhang , linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Jesse Taube , Yangyu Chen , Inochi Amaoto , Jisheng Zhang , Meng Zhang , linux-riscv@lists.infradead.org Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org Implement GPIO functionality which capable of setting pin as input, output. Also, each pin can be used as interrupt which support rising/failing edge type trigger, or both. Signed-off-by: Yixun Lan --- drivers/gpio/Kconfig | 7 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-spacemit-k1.c | 454 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 462 insertions(+) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 93ee3aa092f81cd9573fcf91aef82ede1c5d7130..b525a98a6c176a4e71d2b0f1bd217e7d89141e81 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -655,6 +655,13 @@ config GPIO_SNPS_CREG where only several fields in register belong to GPIO lines and each GPIO line owns a field with different length and on/off value. +config GPIO_SPACEMIT_K1 + bool "SPACEMIT K1 GPIO support" + depends on ARCH_SPACEMIT || COMPILE_TEST + select GPIOLIB_IRQCHIP + help + Say yes here to support the SpacemiT's K1 GPIO device. + config GPIO_SPEAR_SPICS bool "ST SPEAr13xx SPI Chip Select as GPIO support" depends on PLAT_SPEAR diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index af3ba4d81b583842893ea69e677fbe2abf31bc7b..6709ce511a0cf10310a94521c85a2d382dcfa696 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -156,6 +156,7 @@ obj-$(CONFIG_GPIO_SIOX) += gpio-siox.o obj-$(CONFIG_GPIO_SL28CPLD) += gpio-sl28cpld.o obj-$(CONFIG_GPIO_SLOPPY_LOGIC_ANALYZER) += gpio-sloppy-logic-analyzer.o obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o +obj-$(CONFIG_GPIO_SPACEMIT_K1) += gpio-spacemit-k1.o obj-$(CONFIG_GPIO_SPEAR_SPICS) += gpio-spear-spics.o obj-$(CONFIG_GPIO_SPRD) += gpio-sprd.o obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o diff --git a/drivers/gpio/gpio-spacemit-k1.c b/drivers/gpio/gpio-spacemit-k1.c new file mode 100644 index 0000000000000000000000000000000000000000..493ddc99f38c141187b05db6c292bc28ad5331b4 --- /dev/null +++ b/drivers/gpio/gpio-spacemit-k1.c @@ -0,0 +1,454 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Copyright (C) 2023-2024 SpacemiT (Hangzhou) Technology Co. Ltd + * Copyright (c) 2024 Yixun Lan + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* register offset */ +#define GPLR 0x00 +#define GPDR 0x0c +#define GPSR 0x18 +#define GPCR 0x24 +#define GRER 0x30 +#define GFER 0x3c +#define GEDR 0x48 +#define GSDR 0x54 +#define GCDR 0x60 +#define GSRER 0x6c +#define GCRER 0x78 +#define GSFER 0x84 +#define GCFER 0x90 +#define GAPMASK 0x9c +#define GCPMASK 0xa8 + +#define K1_BANK_GPIO_NUMBER (32) +#define BANK_GPIO_MASK (K1_BANK_GPIO_NUMBER - 1) + +#define spacemit_gpio_to_bank_idx(gpio) ((gpio) / K1_BANK_GPIO_NUMBER) +#define spacemit_gpio_to_bank_offset(gpio) ((gpio) & BANK_GPIO_MASK) +#define spacemit_bank_to_gpio(idx, offset) \ + (((idx) * K1_BANK_GPIO_NUMBER) | ((offset) & BANK_GPIO_MASK)) + +static u32 k1_gpio_bank_offset[] = { 0x0, 0x4, 0x8, 0x100 }; + +struct spacemit_gpio_bank { + void __iomem *reg_bank; + u32 irq_mask; + u32 irq_rising_edge; + u32 irq_falling_edge; +}; + +struct spacemit_gpio_chip { + struct gpio_chip chip; + struct irq_domain *domain; + struct spacemit_gpio_bank *banks; + void __iomem *reg_base; + unsigned int ngpio; + unsigned int nbank; + int irq; +}; + +static struct spacemit_gpio_chip *to_spacemit_gpio_chip(struct gpio_chip *chip) +{ + return container_of(chip, struct spacemit_gpio_chip, chip); +} + +static inline void spacemit_clear_edge_detection(struct spacemit_gpio_bank *bank, + u32 bit) +{ + writel(bit, bank->reg_bank + GCRER); + writel(bit, bank->reg_bank + GCFER); +} + +static inline void spacemit_set_edge_detection(struct spacemit_gpio_bank *bank, + u32 bit) +{ + writel(bit & bank->irq_rising_edge, bank->reg_bank + GSRER); + writel(bit & bank->irq_falling_edge, bank->reg_bank + GSFER); +} + +static void spacemit_reset_edge_detection(struct spacemit_gpio_chip *schip) +{ + struct spacemit_gpio_bank *bank; + unsigned int i; + + for (i = 0; i < schip->nbank; i++) { + bank = &schip->banks[i]; + + writel(0xffffffff, bank->reg_bank + GCFER); + writel(0xffffffff, bank->reg_bank + GCRER); + writel(0xffffffff, bank->reg_bank + GAPMASK); + } +} + +static int spacemit_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) +{ + struct spacemit_gpio_chip *schip = to_spacemit_gpio_chip(chip); + + return irq_create_mapping(schip->domain, offset); +} + +static struct spacemit_gpio_bank * +spacemit_gpio_get_bank(struct spacemit_gpio_chip *schip, + unsigned int offset) +{ + return &schip->banks[spacemit_gpio_to_bank_idx(offset)]; +} + +static int spacemit_gpio_direction_input(struct gpio_chip *chip, + unsigned int offset) +{ + struct spacemit_gpio_chip *schip; + struct spacemit_gpio_bank *bank; + u32 bit; + + schip = to_spacemit_gpio_chip(chip); + bank = spacemit_gpio_get_bank(schip, offset); + bit = BIT(spacemit_gpio_to_bank_offset(offset)); + + writel(bit, bank->reg_bank + GCDR); + + return 0; +} + +static int spacemit_gpio_direction_output(struct gpio_chip *chip, + unsigned int offset, int value) +{ + struct spacemit_gpio_chip *schip; + struct spacemit_gpio_bank *bank; + u32 bit; + + schip = to_spacemit_gpio_chip(chip); + bank = spacemit_gpio_get_bank(schip, offset); + bit = BIT(spacemit_gpio_to_bank_offset(offset)); + + writel(bit, bank->reg_bank + (value ? GPSR : GPCR)); + writel(bit, bank->reg_bank + GSDR); + + return 0; +} + +static int spacemit_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + struct spacemit_gpio_chip *schip; + struct spacemit_gpio_bank *bank; + u32 bit, gplr; + + schip = to_spacemit_gpio_chip(chip); + bank = spacemit_gpio_get_bank(schip, offset); + bit = BIT(spacemit_gpio_to_bank_offset(offset)); + + gplr = readl(bank->reg_bank + GPLR); + + return !!(gplr & bit); +} + +static void spacemit_gpio_set(struct gpio_chip *chip, + unsigned int offset, int value) +{ + struct spacemit_gpio_chip *schip; + struct spacemit_gpio_bank *bank; + u32 bit, gpdr; + + schip = to_spacemit_gpio_chip(chip); + bank = spacemit_gpio_get_bank(schip, offset); + bit = BIT(spacemit_gpio_to_bank_offset(offset)); + gpdr = readl(bank->reg_bank + GPDR); + + /* Is it configured as output? */ + if (gpdr & bit) + writel(bit, bank->reg_bank + (value ? GPSR : GPCR)); +} + +#ifdef CONFIG_OF_GPIO +static int spacemit_gpio_of_xlate(struct gpio_chip *chip, + const struct of_phandle_args *gpiospec, + u32 *flags) +{ + struct spacemit_gpio_chip *schip; + + schip = to_spacemit_gpio_chip(chip); + /* GPIO index start from 0. */ + if (gpiospec->args[0] >= schip->ngpio) + return -EINVAL; + + if (flags) + *flags = gpiospec->args[1]; + + return gpiospec->args[0]; +} +#endif + +static int spacemit_gpio_irq_type(struct irq_data *d, unsigned int type) +{ + struct spacemit_gpio_chip *schip; + struct spacemit_gpio_bank *bank; + int gpio = irqd_to_hwirq(d); + u32 bit; + + schip = irq_data_get_irq_chip_data(d); + bank = spacemit_gpio_get_bank(schip, gpio); + bit = BIT(spacemit_gpio_to_bank_offset(gpio)); + + if (type & IRQ_TYPE_EDGE_RISING) { + bank->irq_rising_edge |= bit; + writel(bit, bank->reg_bank + GSRER); + } else { + bank->irq_rising_edge &= ~bit; + writel(bit, bank->reg_bank + GCRER); + } + + if (type & IRQ_TYPE_EDGE_FALLING) { + bank->irq_falling_edge |= bit; + writel(bit, bank->reg_bank + GSFER); + } else { + bank->irq_falling_edge &= ~bit; + writel(bit, bank->reg_bank + GCFER); + } + + return 0; +} + +static irqreturn_t spacemit_gpio_irq_handler(int irq, void *data) +{ + struct spacemit_gpio_chip *schip = data; + struct spacemit_gpio_bank *bank; + unsigned int irqs_handled = 0; + unsigned long pending = 0; + u32 gedr, girq; + int i, n; + + for (i = 0; i < schip->nbank; i++) { + bank = &schip->banks[i]; + + gedr = readl(bank->reg_bank + GEDR); + if (!gedr) + continue; + + writel(gedr, bank->reg_bank + GEDR); + gedr = gedr & bank->irq_mask; + + if (!gedr) + continue; + + pending = gedr; + for_each_set_bit(n, &pending, BITS_PER_LONG) { + girq = irq_find_mapping(schip->domain, + spacemit_bank_to_gpio(i, n)); + handle_nested_irq(girq); + } + + irqs_handled++; + } + + return irqs_handled ? IRQ_HANDLED : IRQ_NONE; +} + +static void spacemit_ack_muxed_gpio(struct irq_data *d) +{ + struct spacemit_gpio_chip *schip; + struct spacemit_gpio_bank *bank; + int gpio = irqd_to_hwirq(d); + u32 bit; + + schip = irq_data_get_irq_chip_data(d); + bank = spacemit_gpio_get_bank(schip, gpio); + bit = BIT(spacemit_gpio_to_bank_offset(gpio)); + + writel(bit, bank->reg_bank + GEDR); +} + +static void spacemit_mask_muxed_gpio(struct irq_data *d) +{ + struct spacemit_gpio_chip *schip; + struct spacemit_gpio_bank *bank; + int gpio = irqd_to_hwirq(d); + u32 bit; + + schip = irq_data_get_irq_chip_data(d); + bank = spacemit_gpio_get_bank(schip, gpio); + bit = BIT(spacemit_gpio_to_bank_offset(gpio)); + + bank->irq_mask &= ~bit; + + spacemit_clear_edge_detection(bank, bit); +} + +static void spacemit_unmask_muxed_gpio(struct irq_data *d) +{ + struct spacemit_gpio_chip *schip; + struct spacemit_gpio_bank *bank; + int gpio = irqd_to_hwirq(d); + u32 bit; + + schip = irq_data_get_irq_chip_data(d); + bank = spacemit_gpio_get_bank(schip, gpio); + bit = BIT(spacemit_gpio_to_bank_offset(gpio)); + + bank->irq_mask |= bit; + + spacemit_set_edge_detection(bank, bit); +} + +static struct irq_chip spacemit_muxed_gpio_chip = { + .name = "k1-gpio-irqchip", + .irq_ack = spacemit_ack_muxed_gpio, + .irq_mask = spacemit_mask_muxed_gpio, + .irq_unmask = spacemit_unmask_muxed_gpio, + .irq_set_type = spacemit_gpio_irq_type, + .flags = IRQCHIP_SKIP_SET_WAKE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + +static int spacemit_irq_domain_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hw) +{ + irq_set_chip_data(irq, d->host_data); + irq_set_chip_and_handler(irq, &spacemit_muxed_gpio_chip, + handle_edge_irq); + + return 0; +} + +static const struct irq_domain_ops spacemit_gpio_irq_domain_ops = { + .map = spacemit_irq_domain_map, + .xlate = irq_domain_xlate_twocell, +}; + +static int spacemit_gpio_probe_dt(struct platform_device *pdev, + struct spacemit_gpio_chip *schip) +{ + void __iomem *reg; + int i, nbank; + + nbank = ARRAY_SIZE(k1_gpio_bank_offset); + + schip->banks = devm_kzalloc(&pdev->dev, + sizeof(*schip->banks) * nbank, + GFP_KERNEL); + if (!schip->banks) + return -ENOMEM; + + for (i = 0; i < nbank; i++) { + reg = schip->reg_base + k1_gpio_bank_offset[i]; + schip->banks[i].reg_bank = reg; + } + + schip->nbank = nbank; + schip->ngpio = nbank * K1_BANK_GPIO_NUMBER; + + return 0; +} + +static void spacemit_gpio_remove_irq_domain(void *data) +{ + struct irq_domain *domain = data; + + irq_domain_remove(domain); +} + +static int spacemit_gpio_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np; + struct spacemit_gpio_chip *schip; + struct irq_domain *domain; + struct resource *res; + void __iomem *base; + int ret; + + np = pdev->dev.of_node; + if (!np) + return -EINVAL; + + schip = devm_kzalloc(dev, sizeof(*schip), GFP_KERNEL); + if (!schip) + return -ENOMEM; + + schip->irq = platform_get_irq(pdev, 0); + if (schip->irq < 0) + return schip->irq; + + base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); + if (IS_ERR(base)) + return PTR_ERR(base); + + schip->reg_base = base; + + ret = spacemit_gpio_probe_dt(pdev, schip); + if (ret) + return dev_err_probe(dev, ret, "Fail to initialize gpio unit\n"); + + spacemit_reset_edge_detection(schip); + + domain = irq_domain_add_linear(np, schip->ngpio, + &spacemit_gpio_irq_domain_ops, + schip); + if (domain == NULL) + return -EINVAL; + + ret = devm_add_action_or_reset(dev, spacemit_gpio_remove_irq_domain, + domain); + if (ret) + return ret; + + schip->domain = domain; + schip->chip.label = "k1-gpio"; + schip->chip.parent = dev; + schip->chip.request = gpiochip_generic_request; + schip->chip.free = gpiochip_generic_free; + schip->chip.direction_input = spacemit_gpio_direction_input; + schip->chip.direction_output = spacemit_gpio_direction_output; + schip->chip.get = spacemit_gpio_get; + schip->chip.set = spacemit_gpio_set; + schip->chip.to_irq = spacemit_gpio_to_irq; +#ifdef CONFIG_OF_GPIO + schip->chip.of_xlate = spacemit_gpio_of_xlate; + schip->chip.of_gpio_n_cells = 2; +#endif + schip->chip.ngpio = schip->ngpio; + schip->chip.base = -1; + + ret = devm_request_threaded_irq(dev, schip->irq, NULL, + spacemit_gpio_irq_handler, + IRQF_ONESHOT, + schip->chip.label, schip); + if (ret < 0) + return dev_err_probe(dev, ret, "failed to request high IRQ\n"); + + ret = devm_gpiochip_add_data(dev, &schip->chip, schip); + if (ret < 0) + return dev_err_probe(dev, ret, "failed to add gpiochip\n"); + + return 0; +} + +static const struct of_device_id spacemit_gpio_dt_ids[] = { + { .compatible = "spacemit,k1-gpio" }, + { /* sentinel */ } +}; + +static struct platform_driver spacemit_gpio_driver = { + .probe = spacemit_gpio_probe, + .driver = { + .name = "k1-gpio", + .of_match_table = spacemit_gpio_dt_ids, + }, +}; +module_platform_driver(spacemit_gpio_driver); + +MODULE_DESCRIPTION("GPIO driver for SpacemiT K1 SoC"); +MODULE_LICENSE("GPL"); From patchwork Thu Dec 19 07:17:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yixun Lan X-Patchwork-Id: 13914549 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 29DC5E77184 for ; Thu, 19 Dec 2024 07:18:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:To:In-Reply-To:References:Message-Id: MIME-Version:Subject:Date:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=T+AmbeGWSQjlxwhnz4Wmk6uDGG+iqH+sP0+F5mMjjVM=; b=pqdJ61dgKsNKO8 iruSQGVf6e7fIanLnm2PAGcULsyaCLKq6Qll2uL1m4veNJKImjOEKnpPEa+qDDfKHiNWJ4q719Mxk 7sfjFt6/QvzW2E++ahqJiMtSUMMywbDuGIDvjKO6kE9pMzHp0pW4msQtdPWqp+swL12vKOMzaqsW+ pGQElw6ZmN35SLw06D6HFCclVSIjo8/iZnuUDXUV3gLzoJkPPLdn0uN7vBx2HPv79EDgMIvTL+gCn /xwSgTEQcI2qWrANOj1/9ublfE4vnRcDQbhfjHQzP2N6/lpGmrSzAcG0RLM9OxVeZAFiQ4TVCO6Qw xuxSGawuU7oP5fXkUV2w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tOAo4-000000013hn-49sv; Thu, 19 Dec 2024 07:18:48 +0000 Received: from woodpecker.gentoo.org ([140.211.166.183] helo=smtp.gentoo.org) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tOAo2-000000013gn-3g0X for linux-riscv@lists.infradead.org; Thu, 19 Dec 2024 07:18:47 +0000 From: Yixun Lan Date: Thu, 19 Dec 2024 15:17:45 +0800 Subject: [PATCH v2 3/3] riscv: dts: spacemit: add gpio support for K1 SoC MIME-Version: 1.0 Message-Id: <20241219-03-k1-gpio-v2-3-28444fd221cd@gentoo.org> References: <20241219-03-k1-gpio-v2-0-28444fd221cd@gentoo.org> In-Reply-To: <20241219-03-k1-gpio-v2-0-28444fd221cd@gentoo.org> To: Linus Walleij , Bartosz Golaszewski , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Conor Dooley , Paul Walmsley , Palmer Dabbelt X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1091; i=dlan@gentoo.org; h=from:subject:message-id; bh=8k9ZtiUx47mbBAMnpFiZwSbwpeenY/eKCaJy4BYVKmc=; b=owEBzQIy/ZANAwAKATGq6kdZTbvtAcsmYgBnY8i4EceF6Gs079MvZbYKcN5sLCLXXWwNziHU3 JPXJwbDXYWJApMEAAEKAH0WIQS1urjJwxtxFWcCI9wxqupHWU277QUCZ2PIuF8UgAAAAAAuAChp c3N1ZXItZnByQG5vdGF0aW9ucy5vcGVucGdwLmZpZnRoaG9yc2VtYW4ubmV0QjVCQUI4QzlDMzF CNzExNTY3MDIyM0RDMzFBQUVBNDc1OTREQkJFRAAKCRAxqupHWU277YI1D/oDKcjA3apmQ3Anjp ebtiMVXd64vaS6P1BS3Q93YZQzYikbuHKCCMrEfkyYgIVSIOYO+NO0KgJ3xkL37q7rkVYnzr/7w LvqaAfI+e0l8jUE0D65ya0BAPkOGYIpEoEdWns2ynXFhqkiJlWpb3NBekZ/YtRoUc6ccugmDIPS XcShp7Qq4/2l75obrkplYCCHVAPobVgaTkN99Fexith6JvQXsQrsrt8gqdgZbGtniX32Mo0gt4K qF19x2ZyRTR7wDaO5QUTHStvF0coZkJGMlc602IOxGoqZpWRLLN0SlE416NEhBrCu5PCmsBzI20 VCCg9ozkr57OjpAKUXxttM2Kvm8/5+Ow8uVOcKTcMSgLPnrlpvrR2JVVlFDzcHEoDNKjLZ7YRIt 9qsAFFB3bV6j5KkKOeT3nI77LECaVyfxVvJJV45BahbGlFpXOVp2+1hP2o0GD4tM35uWIkenuHZ 7Q5O10OkOwxGf1tReMa9Ak/IwXQBPvIfHnz/2oY8Mru3UqT2B8VJuJxwo8t2QdDe/df/MSdQqHO RxgQCmbXkC6dbmAjjemvF8hqhljFUn/HNyu9Ej6B0FVnngSjUha6cKSf55+mMY+1ZsKoUnauJOZ fD943wJIGjp2xNjofyZWLTJ1FERgkQJptObUz3rbeuaffN6tipVryT9xhUe7nZCiu/Kg== X-Developer-Key: i=dlan@gentoo.org; a=openpgp; fpr=50B03A1A5CBCD33576EF8CD7920C0DBCAABEFD55 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20241218_231846_943563_BF10CE70 X-CRM114-Status: UNSURE ( 8.21 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, Yixun Lan , Meng Zhang , linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Jesse Taube , Yangyu Chen , Inochi Amaoto , Jisheng Zhang , Meng Zhang , linux-riscv@lists.infradead.org Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org Populate the GPIO node in the device tree for K1 SoC. Also, map all 128 pins as GPIO to the pinctrl controller. Signed-off-by: Yixun Lan --- arch/riscv/boot/dts/spacemit/k1.dtsi | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/riscv/boot/dts/spacemit/k1.dtsi b/arch/riscv/boot/dts/spacemit/k1.dtsi index a2d5f7d4a942af26b3ba991928f23b2d9943366a..648b459597a4d0ecb6a29881dac76bd4cd749c8c 100644 --- a/arch/riscv/boot/dts/spacemit/k1.dtsi +++ b/arch/riscv/boot/dts/spacemit/k1.dtsi @@ -416,6 +416,19 @@ uart9: serial@d4017800 { status = "disabled"; }; + gpio: gpio@d4019000 { + compatible = "spacemit,k1-gpio"; + reg = <0x0 0xd4019000 0x0 0x800>; + gpio-controller; + #gpio-cells = <2>; + interrupts = <58>; + interrupt-names = "gpio_mux"; + interrupt-parent = <&plic>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&pinctrl 0 0 128>; + }; + pinctrl: pinctrl@d401e000 { compatible = "spacemit,k1-pinctrl"; reg = <0x0 0xd401e000 0x0 0x400>;