From patchwork Wed Dec 25 00:32:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yixun Lan X-Patchwork-Id: 13920568 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 91744E77188 for ; Wed, 25 Dec 2024 00:33:32 +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=vS+dwYfPZLeltx0lHHINwjN7qTf0r5fTgy9j/ULFiyA=; b=XA5+Jx4BO4+BVT SgDmqAcwnIx8Ze49uXjxJrsx2UgkebE9BCJX36Kdm0nsNMCVQRjE4bXoqB2uRqdWdtrAEVWUHfKkx V7kAf/sGLvcwV9DQ8LcrnxQn/mSy30QuqEYvRtqs68uniOkNGGKxu/xN2f9VJWLSxtlAs4Q4uYVL5 DtNWs9ubkgaCyJJ/7rpW57ZU8dqt4Pa+IK2q9AeFBMjs2eZxZbMM63grX2Dsw6mQavhb7IF0d8CGr uKbWInkChXXMg6Ge/8A/z3Ob0dbmn7r4YxIwX9ocdQB63lMNfOhNimIfPGgzLUw1xA9Q3znbqjs/e m7/JVBiRTlLVHD4u0TRQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tQFL5-0000000CzeW-2ojR; Wed, 25 Dec 2024 00:33:27 +0000 Received: from smtp.gentoo.org ([2001:470:ea4a:1:5054:ff:fec7:86e4]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tQFL3-0000000Czdm-1fZd for linux-riscv@lists.infradead.org; Wed, 25 Dec 2024 00:33:26 +0000 From: Yixun Lan Date: Wed, 25 Dec 2024 08:32:39 +0800 Subject: [PATCH v3 1/3] dt-bindings: gpio: spacemit: add support for K1 SoC MIME-Version: 1.0 Message-Id: <20241225-03-k1-gpio-v3-1-27bb7b441d62@gentoo.org> References: <20241225-03-k1-gpio-v3-0-27bb7b441d62@gentoo.org> In-Reply-To: <20241225-03-k1-gpio-v3-0-27bb7b441d62@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=2568; i=dlan@gentoo.org; h=from:subject:message-id; bh=azsMLWSU24kZOm/Gqa8SMlagV4Qub9G9lNilVBghqyI=; b=kA0DAAoBMarqR1lNu+0ByyZiAGdrUr2g757rWEynp1Ky5mHaV0bRmznm0pWMiqscTAKftYugU 4kCkwQAAQoAfRYhBLW6uMnDG3EVZwIj3DGq6kdZTbvtBQJna1K9XxSAAAAAAC4AKGlzc3Vlci1m cHJAbm90YXRpb25zLm9wZW5wZ3AuZmlmdGhob3JzZW1hbi5uZXRCNUJBQjhDOUMzMUI3MTE1Njc wMjIzREMzMUFBRUE0NzU5NERCQkVEAAoJEDGq6kdZTbvtNIEQAIyE4LzGcZuN0fqPdFWbFaWiiW 5cQqKqT8Ul/wyIWPsH+U0LE36bSf5UVs185RzlRuRoGsnkSo0+QWvisclaHZ0ZTAEEATO3ZNs+F tH+4CYVgpoG4d5YEwI9f9M7CVUVOW4HquNMy5nagruWd5RNUcUoDQvBd8h8lGdW/Heyl5JhknNW 0dNfb8Cao9rts99vpB8h2tQ69n0gtoZnHIOGf0uKfchi06siz6NYoQPor9mvhrxzlgwNJBlU1Rf wOxWkmXkxi28LeFCVn4Ja1x1dBWvW/tr6Pm/TUNT0nEaTu4BCp2L7Ae9kSqPPhIbvx9Kwdpm0em IWiRl1AI/yFxLHNcFbXLnnGAsKrTgEuCF08TEVKQUdtvz2V1Kt7ZLb35TYpd9Hb2mGJYKCoTznx WO4A6r6tOHdG+E0kGbvSjnVOtRRPNKt6ubGpJ82jf+rHlH9G6JRKvxRA1bh/Ctr95BPp61hmg4p wOOWDJp3wVtsAlUv/yB9wfwLynbJcC86a9ziYD8omvTeGuAqZmiS1ir66P4Jqoym24bPZLYux9s Yasl9Q9rljSzNsny8IXLvKL9UKbqS2+c6ImjU8ORIgofhY5qI5H2JJynrclWLDIny844SJfnTjL 0jygnGyE7zXab6lmLXcYm8fgO47upExnZPV8kmUQAdwFDOhX+7MMVJ61OL 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-20241224_163325_480763_DE1D01FD X-CRM114-Status: GOOD ( 12.29 ) 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, Meng Zhang , Yixun Lan , linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Jesse Taube , Yangyu Chen , Inochi Amaoto , Jisheng 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 | 69 ++++++++++++++++++++++ 1 file changed, 69 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..6ce8f27bd4a5a85f730420e103ea51710200d301 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/spacemit,k1-gpio.yaml @@ -0,0 +1,69 @@ +# 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 + + "#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-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-controller + - "#interrupt-cells" + +additionalProperties: false + +examples: + - | + gpio@d4019000 { + compatible = "spacemit,k1-gpio"; + reg = <0xd4019000 0x800>; + gpio-controller; + #gpio-cells = <2>; + interrupts = <58>; + interrupt-parent = <&plic>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&pinctrl 0 0 128>; + }; From patchwork Wed Dec 25 00:32:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yixun Lan X-Patchwork-Id: 13920569 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 24E94E77188 for ; Wed, 25 Dec 2024 00:33:39 +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=keB7FJXmBaARYHPYV66AoyA/isrRyLJWyiWa/pICD0o=; b=IQNJJublqj2S7B si85nDNRiMSyj06Zq41yHyYzfmZUHmr9ZUjti6cHZub0G86Fmye/rAzxon8+Vn9lLBL/XUa6oXkrO 9b5MxHmrQwcPDle6aeBe6R3Y6jHVVVol7n5F8d+fN8tNlJfiS7R8dTryVPuVf0ahjLVh1D3o8hqc6 NF6fnfuQS7bLjqrRs7EApv7LjTK79A6hyO/tlLwFlruL/CQbxf1DxcIR6LgFzA9XOFDKXd+Nlk1aj CUb77GnCp9DowRq1lmpUcLEu/PF5VO9xAQHfMwfE9skH3Xf/hmBnJIqROclC8YsYHKEHXz6XLZyeY Zc462n75grzogwxRiWag==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tQFLA-0000000Czfw-1Ibu; Wed, 25 Dec 2024 00:33:32 +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 1tQFL7-0000000Czez-2rfJ for linux-riscv@lists.infradead.org; Wed, 25 Dec 2024 00:33:30 +0000 From: Yixun Lan Date: Wed, 25 Dec 2024 08:32:40 +0800 Subject: [PATCH v3 2/3] gpio: spacemit: add support for K1 SoC MIME-Version: 1.0 Message-Id: <20241225-03-k1-gpio-v3-2-27bb7b441d62@gentoo.org> References: <20241225-03-k1-gpio-v3-0-27bb7b441d62@gentoo.org> In-Reply-To: <20241225-03-k1-gpio-v3-0-27bb7b441d62@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=+BcuvROJqsMP7diCqdsePHBw5W5IedeMTZRzyuJdohs=; b=owEBzQIy/ZANAwAKATGq6kdZTbvtAcsmYgBna1LAeQI9Kbhwi/eiYtexOTWCyOh1fzAW7Hpaa oB5jk4pxE+JApMEAAEKAH0WIQS1urjJwxtxFWcCI9wxqupHWU277QUCZ2tSwF8UgAAAAAAuAChp c3N1ZXItZnByQG5vdGF0aW9ucy5vcGVucGdwLmZpZnRoaG9yc2VtYW4ubmV0QjVCQUI4QzlDMzF CNzExNTY3MDIyM0RDMzFBQUVBNDc1OTREQkJFRAAKCRAxqupHWU277f7nD/43cnKej+WfUV8Z3e ZUJz0acIG4KUUCqI8Yo0E3OUhv2koNyZZfeHVF43SzoBFCRBG7rB2CH10GDIfYiVMEGtgQKRU3o ehFoYmX0pLhKLM8EU/vNGrk+1xMY5uoQqEoa8AXEtWngWacsHdXRKldHkqZ27jxe7mcoAol+Hno lBk5H2yqFl9XEBpgSc1oIoQsu3b4poDyTS7vpbKmdHMjmw+3/WLJ3G1DP+43Koh2Cl/hThByjqI 8oB425srbTJqtySfHKk4da2F3KziQ4SmuuF1GOdk7sXnf61UUcjrHMZjaEy8Le/0w9MwK2ewUhm fVxavQFhfGsLsEPhtxiCl6k1f/aL0vo5Es2oUEwAVsJGOwB98xJ2zXDoKVX1NPopYVV/sBXi0Zo 0ne6FHvHI2VgTxQ7woDcx5kQLuHBlQ5ae33J13i43X/pyOA35jftEWyF0Xfyha1kKi8Hn54GjFn dL3cNlh4L2W3QQKvl2dRHqU9TAkLGxEZr0VPqGjtD76TUNfnIFd9VFsrWfkULcYAire0lU+O/Ew tJUwDuMJ6/t3uyXEUN+Mfy5kujLLDUz28uY106dcIXyxhO7s7BTztM9zOHLWm8R91honepHNqpZ 8MyEFivgsRpn0a3swef8ZmXA+emX7mK9zespPUl95x+Esy6ePgZSrXLO+gYHN/Xxw0gQ== 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-20241224_163329_771566_05336B87 X-CRM114-Status: GOOD ( 22.41 ) 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, Meng Zhang , Yixun Lan , linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Jesse Taube , Yangyu Chen , Inochi Amaoto , Jisheng 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 Wed Dec 25 00:32:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yixun Lan X-Patchwork-Id: 13920570 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 5155FE7718D for ; Wed, 25 Dec 2024 00:33: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=OaUQpJyY432DV6Pmy5p/DqaRxmOb3U0chq4QnS7gniM=; b=NXYdTRZjiFJDUt cdBl5USfH7cTMBmvZJLCGvxYWEl3caSnNSKbxdLGM4KQznjGada4wi2x3CQZ6Sxc+8sLTgzD8ZhEK DzMwnCwo9g7kfMzqHuGeX5CcQSSmXi+u3PE/9y4Ij8AoUEMUZJ18ZMZDJaiwmxDEH4FMtivII0E7J gyKnX+QTlUHlPT94egjYol85/3TSz49pxWdABemQ0d0xZhns9SWCsAvF8MpJ7EmWUDg2IaF9abUs7 5xDjf1cyHtcgpmQakiCcTpulOJc0x6VmwyrB3AwYOBHq9iSsrAuVtrW2Mtd7wzhKfBWYs0FQIHKlc +WdZ77DMaezkQu7UBMJg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tQFLF-0000000CzhF-034s; Wed, 25 Dec 2024 00:33:37 +0000 Received: from smtp.gentoo.org ([2001:470:ea4a:1:5054:ff:fec7:86e4]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tQFLD-0000000Czgl-15pY for linux-riscv@lists.infradead.org; Wed, 25 Dec 2024 00:33:36 +0000 From: Yixun Lan Date: Wed, 25 Dec 2024 08:32:41 +0800 Subject: [PATCH v3 3/3] riscv: dts: spacemit: add gpio support for K1 SoC MIME-Version: 1.0 Message-Id: <20241225-03-k1-gpio-v3-3-27bb7b441d62@gentoo.org> References: <20241225-03-k1-gpio-v3-0-27bb7b441d62@gentoo.org> In-Reply-To: <20241225-03-k1-gpio-v3-0-27bb7b441d62@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=1055; i=dlan@gentoo.org; h=from:subject:message-id; bh=AySrMTveJUwwqh3zG/JqbY/pPxQJ1p6ycMJxkwoG/gA=; b=owEBzQIy/ZANAwAKATGq6kdZTbvtAcsmYgBna1LEBQFMqC3ZhScCywepFcpG6RzRKU+OFbTPM fSiW6ix5aSJApMEAAEKAH0WIQS1urjJwxtxFWcCI9wxqupHWU277QUCZ2tSxF8UgAAAAAAuAChp c3N1ZXItZnByQG5vdGF0aW9ucy5vcGVucGdwLmZpZnRoaG9yc2VtYW4ubmV0QjVCQUI4QzlDMzF CNzExNTY3MDIyM0RDMzFBQUVBNDc1OTREQkJFRAAKCRAxqupHWU277dt4D/9kr6A3nhOojcBbd3 7Wf+9AjNtpQvQ7IQQ4qVBzyhfB1WpmQlGFc9Y3T6yYhGaC2qS6gUTPFvLIdg8pxzyP2iP7PT3D2 K9L1FG/77l+7Z2N5JpIoGiAPL/NVAB1Jju7VN00hhi/SwDMfkqJRtZRoEm011rFEw8l4UKltg8u MNyMd3424Y3zft2JDoN/pvglijSIvnAjc0rIJ9t+We9Y/47ODaCuXDs0+YsM7qcTVbxzlhBXUZN kDYDG4Fnor6Xs//n4yA4bH2TQU2sUa6hMDgzqUEvGl08c6ZTPRNFt9KzIiIiI4IWA88Cey/gNSt Yt1bfx/elDL1W/VMn+WhfHXRsKfhWR1o7GjEurYUssSNqEk3Le8m8veduO3bBSxz0FD/gBi/VWp tjb61DAj2oo85xLEpvoRL0iH02eKRqNV9Ghu8iwH3yWRt3kOfzZ/DJDGpKxpFApQxdvKQkDlfmK JMBJygesalq0BHcxn/Qfg2bh6ISQk/D5rgaZYCNBwXcNdhvHPx6gq4XOmXzjjQbknB/HQ0RZLoC OLtnlQxmmWvE2DuMVDQ4/VpEnBjsgaa7/IEYY4SRzWcz9+OEQEPnQm1aVQvV0oDkstmeqXAn6R2 qTZzxSNNVpiGXO2PEnM8B7LBCWxD+AVM60WQbHUwwgHKMedsqna2PA0u/w8TtC+TLMQw== 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-20241224_163335_335500_63E87E29 X-CRM114-Status: UNSURE ( 7.46 ) 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, Meng Zhang , Yixun Lan , linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Jesse Taube , Yangyu Chen , Inochi Amaoto , Jisheng 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 | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/riscv/boot/dts/spacemit/k1.dtsi b/arch/riscv/boot/dts/spacemit/k1.dtsi index a2d5f7d4a942af26b3ba991928f23b2d9943366a..bdd25584d67c9a9e41f8d8227fe84a1bdeed7b41 100644 --- a/arch/riscv/boot/dts/spacemit/k1.dtsi +++ b/arch/riscv/boot/dts/spacemit/k1.dtsi @@ -416,6 +416,18 @@ 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-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>;