From patchwork Wed Dec 6 01:45:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Liu X-Patchwork-Id: 174267 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:bcd1:0:b0:403:3b70:6f57 with SMTP id r17csp3825828vqy; Tue, 5 Dec 2023 17:46:49 -0800 (PST) X-Google-Smtp-Source: AGHT+IE/g9V9BOvp9tJpux4Mxols96q99+PcV2FeDpGoZmx7ISa7mDohHkwEHAtq0mrPxYBm4Md7 X-Received: by 2002:a17:902:6bc5:b0:1d0:afd5:1e93 with SMTP id m5-20020a1709026bc500b001d0afd51e93mr102896plt.8.1701827209430; Tue, 05 Dec 2023 17:46:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701827209; cv=none; d=google.com; s=arc-20160816; b=Vl0Fk0g0ZfFvQAYod5X2cutGF4GmuQeGHijABIRULjCv0mWQC8XFE3jOe85flIJxJg gz0qIh2Y3lp1qOlxQ869QSdJAt0U7ZOk0xvGN3D8FsCFE2rF1J19/n4BGmjCDD8Xvlh2 seMzEnuq4ZaFBpij+htNswkaUCvFJ9XZkKhUTN49jzgjBCj3UvtEji+zLlJcJeHjmMoX pFZScugs+5pA3/TR3g6iOwRUkhztwjsW+7IuIyAFRHnVq0H6hIouDZzNC/Mn/qi8vAsQ qu1nlDyzcLZkttoXBqv9cYqnu8R+7uxl5id5dxCF8XdUcbW1OUmM+0DplKdUS29Gaucr xoGw== 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; bh=csVIocKJcCA0/pKL9VAYyHAhw6hsvYWEU7r5aRbgOmA=; fh=q1cHK1FWGDfuI/+7+aLpzVSgaJN0R+iQyw4dSIrRA5c=; b=ab7KEkffjbj9GGCYtMZ8rZNGRrArUvHQVcNtcD64CWXrZizUCyau6wCJuCvMKQLtkl YVb0RI3e+8evNH3VJpa9eTvlBjnAfFLOimjLVYqKVJokbigNAdsRlhYhoTjL4YnM1g/F VssGkhhbGxxuRrydTVrn82yBzWi+SHhi+NOl6cjjT6nQhhVhFX4hfSSD1lDOVbNa4D5c qV6m1T/8fk9GyVmqlo/BBHkDERwY7zTnYnlv9VqnYOk6gFJyC0V/uMAH3PY6R4ddmU0I PAehuxOpGr1Y5D7owCzvcrtKwiX0oA014Bes5Plj/91MZAlPmGE7VwcpZ7VUeh5sy279 480Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=k7ZYZ6fX; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from snail.vger.email (snail.vger.email. [23.128.96.37]) by mx.google.com with ESMTPS id b3-20020a170902d50300b001d08cfd46absi5428554plg.372.2023.12.05.17.46.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Dec 2023 17:46:49 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) client-ip=23.128.96.37; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=k7ZYZ6fX; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id DCBB6802FB8A; Tue, 5 Dec 2023 17:46:47 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376613AbjLFBqi (ORCPT + 99 others); Tue, 5 Dec 2023 20:46:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60734 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235372AbjLFBqb (ORCPT ); Tue, 5 Dec 2023 20:46:31 -0500 Received: from mail-ot1-x331.google.com (mail-ot1-x331.google.com [IPv6:2607:f8b0:4864:20::331]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 12EEA10EA; Tue, 5 Dec 2023 17:46:17 -0800 (PST) Received: by mail-ot1-x331.google.com with SMTP id 46e09a7af769-6d9a3c035b3so1687457a34.2; Tue, 05 Dec 2023 17:46:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701827176; x=1702431976; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=csVIocKJcCA0/pKL9VAYyHAhw6hsvYWEU7r5aRbgOmA=; b=k7ZYZ6fXc2kx0u0FG8a/3Ng1nNeGr3DiZp3+rUGvX8dpgBvYMGAWAcjRW6CZNaTG5b cNwD/9FuVwqZlZrIZwyTrrJsyHQ5JDT9LvFs9cHk9hGruEt7f9FxEUBJb2OjULNOIiOk kUzhsz8pzJIYZxtsiKcsB0ihWDjdgSD/D8D0g5BMZDmOdWHDbTfH4LGHt+NLchB82gBc c1XvPjVjc+0HofcwjC281M6P74TmNmLQ0nitFM9yljaCzPiHGdko73y6w1wvTjEvKD4i jStVuwa9RqIzZRtXAyUXHW9YDheg+lizDec1cbVXgfSzjBVdcw0qREYqZVQ9I0xr/qyF hvMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701827176; x=1702431976; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=csVIocKJcCA0/pKL9VAYyHAhw6hsvYWEU7r5aRbgOmA=; b=HoyE4GfDaMD+MezOAlcwmQ3Zb8T+BtW7QsBpzX0Uj6EQ5RPaOjp20R/shRZVGOBFGw JkU/OlBq2TOFoC5ds0nvd662iAp5HiKM1jU+mHtGnrSAheeHZSmKviJJD5AfPuUxrAac 2CzMFExDMUhM1LAR1Gl5auiThHCFbae0YiqYlDfBE8WqZiyP/m8d7zN9MLiiNgJ1x3Zg BDkbeJdmm2z8jfBWpMx8r4ENT8f3vt+VY+cbLtQ2Omrfe88MKPzPuko8uDraOgU4qjof rW9F8PbEebdNIWFz14ufE80ML9l9uF6YHinGFrn85zH4W9zddNPzbCp8z0WgKsYa7JZ1 Gtcw== X-Gm-Message-State: AOJu0Ywp5QFjhep9aLqjo97GZ3adIW2pdrb46L2CvXjBjN+Z/9CWedV8 aukkvXWEt2CVM9ILCjWdb4F3gfNn4Z2Z8g== X-Received: by 2002:a05:6830:1681:b0:6d8:e05b:115b with SMTP id k1-20020a056830168100b006d8e05b115bmr266085otr.7.1701827176057; Tue, 05 Dec 2023 17:46:16 -0800 (PST) Received: from localhost.localdomain ([112.78.94.69]) by smtp.gmail.com with ESMTPSA id g24-20020aa78758000000b006ce781f6f85sm1250956pfo.43.2023.12.05.17.46.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Dec 2023 17:46:15 -0800 (PST) From: Jim Liu To: JJLIU0@nuvoton.com, krzysztof.kozlowski+dt@linaro.org, linus.walleij@linaro.org, andy@kernel.org, robh+dt@kernel.org, conor+dt@kernel.org, KWLIU@nuvoton.com, jim.t90615@gmail.com Cc: linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, openbmc@lists.ozlabs.org, Rob Herring Subject: [PATCH v8 1/3] dt-bindings: gpio: add NPCM sgpio driver bindings Date: Wed, 6 Dec 2023 09:45:28 +0800 Message-Id: <20231206014530.1600151-2-jim.t90615@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231206014530.1600151-1-jim.t90615@gmail.com> References: <20231206014530.1600151-1-jim.t90615@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Tue, 05 Dec 2023 17:46:48 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1784495168112189214 X-GMAIL-MSGID: 1784495168112189214 Add dt-bindings document for the Nuvoton NPCM7xx sgpio driver Signed-off-by: Jim Liu Reviewed-by: Linus Walleij Reviewed-by: Rob Herring --- Changes for v8: - no changed Changes for v7: - no changed Changes for v6: - Drop quotes for $ref - Add and drop '|' for description - Add space after 'exposed.' - remove status --- .../bindings/gpio/nuvoton,sgpio.yaml | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpio/nuvoton,sgpio.yaml diff --git a/Documentation/devicetree/bindings/gpio/nuvoton,sgpio.yaml b/Documentation/devicetree/bindings/gpio/nuvoton,sgpio.yaml new file mode 100644 index 000000000000..84e0dbcb066c --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/nuvoton,sgpio.yaml @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/gpio/nuvoton,sgpio.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Nuvoton SGPIO controller + +maintainers: + - Jim LIU + +description: | + This SGPIO controller is for NUVOTON NPCM7xx and NPCM8xx SoC. + Nuvoton NPCM7xx SGPIO module is combine serial to parallel IC (HC595) + and parallel to serial IC (HC165), and use APB3 clock to control it. + This interface has 4 pins (D_out , D_in, S_CLK, LDSH). + NPCM7xx/NPCM8xx have two sgpio module each module can support up + to 64 output pins,and up to 64 input pin, the pin is only for gpi or gpo. + GPIO pins have sequential, First half is gpo and second half is gpi. + GPIO pins can be programmed to support the following options + - Support interrupt option for each input port and various interrupt + sensitivity option (level-high, level-low, edge-high, edge-low) + - ngpios is number of nuvoton,input-ngpios GPIO lines and nuvoton,output-ngpios GPIO lines. + nuvoton,input-ngpios GPIO lines is only for gpi. + nuvoton,output-ngpios GPIO lines is only for gpo. + +properties: + compatible: + enum: + - nuvoton,npcm750-sgpio + - nuvoton,npcm845-sgpio + + reg: + maxItems: 1 + + gpio-controller: true + + '#gpio-cells': + const: 2 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + nuvoton,input-ngpios: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + The numbers of GPIO's exposed. GPIO lines is only for gpi. + minimum: 0 + maximum: 64 + + nuvoton,output-ngpios: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + The numbers of GPIO's exposed. GPIO lines is only for gpo. + minimum: 0 + maximum: 64 + +required: + - compatible + - reg + - gpio-controller + - '#gpio-cells' + - interrupts + - nuvoton,input-ngpios + - nuvoton,output-ngpios + - clocks + +additionalProperties: false + +examples: + - | + #include + #include + gpio8: gpio@101000 { + compatible = "nuvoton,npcm750-sgpio"; + reg = <0x101000 0x200>; + clocks = <&clk NPCM7XX_CLK_APB3>; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + nuvoton,input-ngpios = <64>; + nuvoton,output-ngpios = <64>; + }; From patchwork Wed Dec 6 01:45:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Liu X-Patchwork-Id: 174268 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:bcd1:0:b0:403:3b70:6f57 with SMTP id r17csp3825872vqy; Tue, 5 Dec 2023 17:46:59 -0800 (PST) X-Google-Smtp-Source: AGHT+IEneAegCj8jaxlSDQuoUIZr5riIhh7SfBXxIGKmE9grzuRuDkikuSLbXNZBz635vb2mDFJ/ X-Received: by 2002:a05:6358:7e0b:b0:16e:5deb:1df6 with SMTP id o11-20020a0563587e0b00b0016e5deb1df6mr270436rwm.31.1701827219455; Tue, 05 Dec 2023 17:46:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701827219; cv=none; d=google.com; s=arc-20160816; b=NroRto2s5XB+OTfRw8y7EDs6IBiccrOIkifL2aCg9Bnhv+tqFEPRXKqM7b1ivxic1T IENInP7pPXdvsR9RrdmmkN2VBhV9+W/i/+E6IDaHsQ1/wmgFGIP37+N1nN2120Bii7e/ xOecN8j2iaimvATRF8zGLo8ufLF3ItbPRBWt4Zzlw28m14dZCuPJYjTNAdy0D8DUVU0X E9+N6WTPBWEjHhOWtNPOYNrraM/zo/veUasXEgxDO5j4FIqFV3je66Z9derT5JoXd+fa X44InwVK0105A3kdUvh0Px6GnHwKXfDwC8UGax8P1WeENCF60r0snz7HMdasjPBhHJag Bh1A== 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; bh=6cnQl6rrS5sD2qm7iZDbkr4tzTgzBdd00wWO4ndD9wA=; fh=lKSWIbm60Rmc7Xe6HrD15tUfQGnI1b/mOqFZaP/0X9c=; b=FNchd3ka6R+KOkK7hc+jbU/ttWMwt+SsVXlh12ZrHc/AMaBoh+HKefUh4pQTRFOFaH lekz6eVKj8p1vsXCdkP1EFWvClmktg22ebIaTzYzfBoFQ3I9LQnhRgX/LUj3toKK1+mg KY1aD2b3tT+2l7E8e5Knr1GLK/NDVQUi3iuLTLqTL+iapA30mLpU3Fz+126FJuk1MlgU mQP5vpwZLadAlpJY1sluyRuNWRAPPRnKkOj2bhZP4TacXYkV23BulLCpbMrhJ28HzSJr dX4z81Duo66TDjo7rIHQJorTwX6us9f87p703txHo4GMLT2NFy0hAXT9CMaiMLsu8vJN MFVQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=NMqJL9ij; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from snail.vger.email (snail.vger.email. [23.128.96.37]) by mx.google.com with ESMTPS id j11-20020a170902da8b00b001d080a72b2fsi2196860plx.289.2023.12.05.17.46.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Dec 2023 17:46:59 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) client-ip=23.128.96.37; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=NMqJL9ij; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 7732F802FB95; Tue, 5 Dec 2023 17:46:58 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376616AbjLFBqn (ORCPT + 99 others); Tue, 5 Dec 2023 20:46:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33564 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235266AbjLFBqd (ORCPT ); Tue, 5 Dec 2023 20:46:33 -0500 Received: from mail-pf1-x433.google.com (mail-pf1-x433.google.com [IPv6:2607:f8b0:4864:20::433]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A58C310D2; Tue, 5 Dec 2023 17:46:25 -0800 (PST) Received: by mail-pf1-x433.google.com with SMTP id d2e1a72fcca58-6ce93552cb5so13893b3a.3; Tue, 05 Dec 2023 17:46:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701827185; x=1702431985; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=6cnQl6rrS5sD2qm7iZDbkr4tzTgzBdd00wWO4ndD9wA=; b=NMqJL9ijvtpDq2XsJRVd9HT8LlB0A1FyzhVTyG1b7vGGSjbP4hAJipT9iA9hi9N81T bauUBCm8RbpnvHtyvsbNruOfmUwblQFlEvVJRzx+3A55FJahRlJ+6mx6k4+hCcPzs0+O RthwNY+hpJiIvoC4uaeKj2EjpkeB+z7/1Bwa9sVyIS+McbRkAItF1nPfjj7aaLuMeeFj 2s4war9zckih0+UtJGmKmcJ/g0cmF8SzkRPZB165Uj1ycokt9T6VHB9+epJcLWjTkrax lAGZ5F2rYmOzoEZJcyNFjCFsHGfJcMVSJ88/+fS6QuMo/6cRBeccILb8ggq0X8V4QTmG kkkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701827185; x=1702431985; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=6cnQl6rrS5sD2qm7iZDbkr4tzTgzBdd00wWO4ndD9wA=; b=SR9jBChRWynvIMusrEdaLg0dYPyj+CGiZTyt5vC9r0R4tm2iMaexDUi6RTUXOUDPhf dhIMuZ5vizbUQyFykRa0I34+TcP2RrjtDr9idtrf2IHYCowTFShJnRUjvrbzZnvYzlae lT0sj2iDTxFaXGsUBufYRz8zIrg4fPOJVVxI9ghJpdyLCiJ7ivYrs6JFcS9skJbMwFHs tWuIqqkMBCYMQeiFMefhLp/aI525gqfB/hfxeIyW5b/k5rrK1p2X9ZXeJ3Kvj9P5+VmL +ekOIEUVjnOnISFukhAnZdwwUs3jcD5wK+PHiQivbCcfBBFeUa/6CsxDRpry3zavib0U hyjQ== X-Gm-Message-State: AOJu0YxjlmFTreWoDznKDKj5tWSwpKu3xwIIb3k+A0pVkvq41H4yi7zj yH+/YQ0LLvsxy9UO97A5gdQ= X-Received: by 2002:a05:6a00:22cc:b0:6ce:5b63:3017 with SMTP id f12-20020a056a0022cc00b006ce5b633017mr63296pfj.53.1701827185024; Tue, 05 Dec 2023 17:46:25 -0800 (PST) Received: from localhost.localdomain ([112.78.94.69]) by smtp.gmail.com with ESMTPSA id g24-20020aa78758000000b006ce781f6f85sm1250956pfo.43.2023.12.05.17.46.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Dec 2023 17:46:24 -0800 (PST) From: Jim Liu To: JJLIU0@nuvoton.com, krzysztof.kozlowski+dt@linaro.org, linus.walleij@linaro.org, andy@kernel.org, robh+dt@kernel.org, conor+dt@kernel.org, KWLIU@nuvoton.com, jim.t90615@gmail.com Cc: linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, openbmc@lists.ozlabs.org Subject: [PATCH v8 2/3] arm: dts: nuvoton: npcm: Add sgpio feature Date: Wed, 6 Dec 2023 09:45:29 +0800 Message-Id: <20231206014530.1600151-3-jim.t90615@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231206014530.1600151-1-jim.t90615@gmail.com> References: <20231206014530.1600151-1-jim.t90615@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Tue, 05 Dec 2023 17:46:58 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1784495178448652336 X-GMAIL-MSGID: 1784495178448652336 Add the SGPIO controller to the NPCM7xx devicetree Signed-off-by: Jim Liu --- Changes for v8: - no changed Changes for v7: - no changed Changes for v6: - remove bus-frequency - check with dtbs_check --- .../dts/nuvoton/nuvoton-common-npcm7xx.dtsi | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/arch/arm/boot/dts/nuvoton/nuvoton-common-npcm7xx.dtsi b/arch/arm/boot/dts/nuvoton/nuvoton-common-npcm7xx.dtsi index 868454ae6bde..df91517a4842 100644 --- a/arch/arm/boot/dts/nuvoton/nuvoton-common-npcm7xx.dtsi +++ b/arch/arm/boot/dts/nuvoton/nuvoton-common-npcm7xx.dtsi @@ -372,6 +372,30 @@ &fanin12_pins &fanin13_pins status = "disabled"; }; + gpio8: gpio@101000 { + compatible = "nuvoton,npcm750-sgpio"; + reg = <0x101000 0x200>; + clocks = <&clk NPCM7XX_CLK_APB3>; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + nuvoton,input-ngpios = <64>; + nuvoton,output-ngpios = <64>; + status = "disabled"; + }; + + gpio9: gpio@102000 { + compatible = "nuvoton,npcm750-sgpio"; + reg = <0x102000 0x200>; + clocks = <&clk NPCM7XX_CLK_APB3>; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + nuvoton,input-ngpios = <64>; + nuvoton,output-ngpios = <64>; + status = "disabled"; + }; + i2c0: i2c@80000 { reg = <0x80000 0x1000>; compatible = "nuvoton,npcm750-i2c"; From patchwork Wed Dec 6 01:45:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Liu X-Patchwork-Id: 174269 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:bcd1:0:b0:403:3b70:6f57 with SMTP id r17csp3825902vqy; Tue, 5 Dec 2023 17:47:05 -0800 (PST) X-Google-Smtp-Source: AGHT+IG5IcMhzT9eWN9ubedSf35SbmlH7ayoc7vP7jJdcxCKmF20++ZH4170pLxD9Xe9mYCHzwvc X-Received: by 2002:a17:90b:4b0f:b0:280:280c:efe3 with SMTP id lx15-20020a17090b4b0f00b00280280cefe3mr196062pjb.14.1701827224969; Tue, 05 Dec 2023 17:47:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701827224; cv=none; d=google.com; s=arc-20160816; b=aNa/XHZZRIPjVHajkSLioPs0XKzj+0rKuP3Q/oS4CqfNfq4vh7d9Eicb3EvkKy8kE4 aXVVsHj9JkcggLlCr1+VNLQHJx3QB5I66I1ZROhQioqgx9movEhluDoLtaSv+holr3Cu 5AD2wILx/9I4UNrCptKniXkLY6VC8eb4el2Gs6iuokoMfN43cpYfYuqJ4m0HO8kWPwDd 0E6x2nY5ajJT7zwv9sn0TjIoXRfRGtyI3Ldgjm5+rW4x6aiJ+YJR/Zgcpj3skRhDnrYl dYuDw14p+h6O+Oz/+VLowwCXd2ZB6v1122C1yK2s+UU3F6QjalxR4IWY7Z8IC5WKLiQu WQ/g== 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; bh=1kXu/UPxVKmDhF7qMSok5hl4RMufr9c58lvSU1Ok2Xo=; fh=lKSWIbm60Rmc7Xe6HrD15tUfQGnI1b/mOqFZaP/0X9c=; b=pK5uO3PHLXIktGbhcyf3h0e739tNXyHves0WfGHuBINzHl6emZ3btcP05wbDcj37Eq L9SKaJ4MKjWfObVnyQJ9Ymkiny20rl4gykaLY3g+nWko2qnPbDkmGIV1LOyjH9yliKfQ BxC9S7qKA9Fo3k3/0+2+uUWW+E8vEjhmH4O2FGx0mIVDBxWp+Qh8LMJUdXi+ibf7dzyR wigiqSBz69CYQLhuVfOx/fsl+NEyKarYjBhV0sTcxpYICRzH6TsUux0J8v2dmBRLzZIN niQWer39EY0WVHwxvYt8DfUJjEibuz1gCr7wWgHyjZkUFzOp13n7rBQOWuzeW2CFRD9K ssHQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=bGVtiVy0; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from snail.vger.email (snail.vger.email. [2620:137:e000::3:7]) by mx.google.com with ESMTPS id oa4-20020a17090b1bc400b00286acacd596si4480348pjb.136.2023.12.05.17.47.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Dec 2023 17:47:04 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) client-ip=2620:137:e000::3:7; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=bGVtiVy0; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id BE3B7802FBB3; Tue, 5 Dec 2023 17:47:03 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235561AbjLFBqu (ORCPT + 99 others); Tue, 5 Dec 2023 20:46:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56812 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235288AbjLFBqg (ORCPT ); Tue, 5 Dec 2023 20:46:36 -0500 Received: from mail-pf1-x433.google.com (mail-pf1-x433.google.com [IPv6:2607:f8b0:4864:20::433]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 30EBED4D; Tue, 5 Dec 2023 17:46:31 -0800 (PST) Received: by mail-pf1-x433.google.com with SMTP id d2e1a72fcca58-6ce6d926f76so291904b3a.1; Tue, 05 Dec 2023 17:46:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701827190; x=1702431990; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=1kXu/UPxVKmDhF7qMSok5hl4RMufr9c58lvSU1Ok2Xo=; b=bGVtiVy0zqCXUX727WqiSU5PdgUWwe7DMqYUMua85oKTGfirzIVNcT6skPI3Qb/4LN Wofnx5GhMBEUPPREwtQjNgpX5LUQuxyP4g8MhLxO4RPqIlrNc+5c73nG3HmG41x+SR4w gTuVFJwHdSZlwKibmSl3xVyElrLXgl6Z7ZPbKrZ81UC6ftn5vm/szDP4Nt2NV+X/lZs9 55Lou+Tsc2GqXCxHtA0v6LE5KECr1xeSYlfnwDyx74xCMFfd1Nn9YDw0HKtm1FjFxXZY HlzUiSkt/ZIkVnmSVoapuC8aDEZvccP9jmH1fN+vqaDN6F4z3lHu49i5rhbQw/rE+0QP dhQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701827190; x=1702431990; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1kXu/UPxVKmDhF7qMSok5hl4RMufr9c58lvSU1Ok2Xo=; b=kz9gdp+uzq1XY9whj4WVl5k7ccQxR67jFvjHZnw6CSk2vySJ2OK5p5LBu/UPkRkQxA pWqnCr1iX/ErNzV3OQCJ+FN3F1ALMjBQv4Yj5HBq2vkeDBEYIAI2j7fR8nl2URbByIq4 xXB9LSNKMCwDeG67+I8IN4KBxEi4KXC0LDKRTDFijW1wJAiccn5hZ/XXBNDCRGNc54Z9 v5V/IlXVzKlONiXC1+ZflHdbWp/sj5xxZJUl4dsBJrF/kMV4dadAyUr3x2HmBuoNzLaO PTlWROyylld4gjEKfAYZ+tl23tQMp5S0gQ4LUAkxTh1hG/utY8MLB3+zx3seIM8Xusju 9uQQ== X-Gm-Message-State: AOJu0Yw9cbbLY4A4VJVSTFB6LZ8aSKoPE/+gPqNUSaW0vkvvAL+F8kYr OXL+/NHXfL9xqkBIiXcR6irFZs1x3ts/QQ== X-Received: by 2002:a05:6a20:3cab:b0:187:a9b0:434b with SMTP id b43-20020a056a203cab00b00187a9b0434bmr167638pzj.4.1701827190447; Tue, 05 Dec 2023 17:46:30 -0800 (PST) Received: from localhost.localdomain ([112.78.94.69]) by smtp.gmail.com with ESMTPSA id g24-20020aa78758000000b006ce781f6f85sm1250956pfo.43.2023.12.05.17.46.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Dec 2023 17:46:30 -0800 (PST) From: Jim Liu To: JJLIU0@nuvoton.com, krzysztof.kozlowski+dt@linaro.org, linus.walleij@linaro.org, andy@kernel.org, robh+dt@kernel.org, conor+dt@kernel.org, KWLIU@nuvoton.com, jim.t90615@gmail.com Cc: linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, openbmc@lists.ozlabs.org Subject: [PATCH v8 3/3] gpio: nuvoton: Add Nuvoton NPCM sgpio driver Date: Wed, 6 Dec 2023 09:45:30 +0800 Message-Id: <20231206014530.1600151-4-jim.t90615@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231206014530.1600151-1-jim.t90615@gmail.com> References: <20231206014530.1600151-1-jim.t90615@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Tue, 05 Dec 2023 17:47:04 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1784495183942054036 X-GMAIL-MSGID: 1784495183942054036 Add Nuvoton BMC NPCM7xx/NPCM8xx sgpio driver support. Nuvoton NPCM SGPIO module is combine serial to parallel IC (HC595) and parallel to serial IC (HC165), and use APB3 clock to control it. This interface has 4 pins (D_out , D_in, S_CLK, LDSH). BMC can use this driver to increase 64 GPI pins and 64 GPO pins to use. Signed-off-by: Jim Liu --- Changes for v8: - Remove OF_GPIO/GPIO_GENERIC and redundant assignments - Use GENMASK() and BIT() - Use dev_WARN and dev_err_probe - Check indentation issue - Use raw_spinlock_t Changes for v7: - Remove unused variable - Remove return in bank_reg function - Fix warning for const issue --- drivers/gpio/Kconfig | 7 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-npcm-sgpio.c | 637 +++++++++++++++++++++++++++++++++ 3 files changed, 645 insertions(+) create mode 100644 drivers/gpio/gpio-npcm-sgpio.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index b3a133ed31ee..efbdc93819d4 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -478,6 +478,13 @@ config GPIO_MXS select GPIO_GENERIC select GENERIC_IRQ_CHIP +config GPIO_NPCM_SGPIO + bool "Nuvoton SGPIO support" + depends on ARCH_NPCM || COMPILE_TEST + select GPIOLIB_IRQCHIP + help + Say Y here to support Nuvoton NPCM7XX/NPCM8XX SGPIO functionality. + config GPIO_OCTEON tristate "Cavium OCTEON GPIO" depends on CAVIUM_OCTEON_SOC diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index eb73b5d633eb..373aa2943de5 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -116,6 +116,7 @@ obj-$(CONFIG_GPIO_MT7621) += gpio-mt7621.o obj-$(CONFIG_GPIO_MVEBU) += gpio-mvebu.o obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o +obj-$(CONFIG_GPIO_NPCM_SGPIO) += gpio-npcm-sgpio.o obj-$(CONFIG_GPIO_OCTEON) += gpio-octeon.o obj-$(CONFIG_GPIO_OMAP) += gpio-omap.o obj-$(CONFIG_GPIO_PALMAS) += gpio-palmas.o diff --git a/drivers/gpio/gpio-npcm-sgpio.c b/drivers/gpio/gpio-npcm-sgpio.c new file mode 100644 index 000000000000..52dde726f175 --- /dev/null +++ b/drivers/gpio/gpio-npcm-sgpio.c @@ -0,0 +1,637 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Nuvoton NPCM Serial GPIO Driver + * + * Copyright (C) 2021 Nuvoton Technologies + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_NR_HW_SGPIO 64 + +#define NPCM_IOXCFG1 0x2A +#define NPCM_IOXCFG1_SFT_CLK GENMASK(3, 0) +#define NPCM_IOXCFG1_SCLK_POL BIT(4) +#define NPCM_IOXCFG1_LDSH_POL BIT(5) + +#define NPCM_IOXCTS 0x28 +#define NPCM_IOXCTS_IOXIF_EN BIT(7) +#define NPCM_IOXCTS_RD_MODE GENMASK(2, 1) +#define NPCM_IOXCTS_RD_MODE_PERIODIC BIT(2) + +#define NPCM_IOXCFG2 0x2B +#define NPCM_IOXCFG2_PORT GENMASK(3, 0) + +#define NPCM_IXOEVCFG_MASK GENMASK(1, 0) +#define NPCM_IXOEVCFG_FALLING BIT(1) +#define NPCM_IXOEVCFG_RISING BIT(0) +#define NPCM_IXOEVCFG_BOTH (NPCM_IXOEVCFG_FALLING | NPCM_IXOEVCFG_RISING) + +#define NPCM_CLK_MHZ 8000000 + +#define GPIO_BANK(x) ((x) / 8) +#define GPIO_BIT(x) ((x) % 8) + +/* + * Select the frequency of shift clock. + * The shift clock is a division of the APB clock. + */ +struct npcm_clk_cfg { + unsigned int *sft_clk; + unsigned int *clk_sel; + unsigned int cfg_opt; +}; + +struct npcm_sgpio { + struct gpio_chip chip; + struct clk *pclk; + struct irq_chip intc; + raw_spinlock_t lock; /*protect event config*/ + void __iomem *base; + int irq; + u8 nin_sgpio; + u8 nout_sgpio; + u8 in_port; + u8 out_port; + u8 int_type[MAX_NR_HW_SGPIO]; +}; + +struct npcm_sgpio_bank { + u8 rdata_reg; + u8 wdata_reg; + u8 event_config; + u8 event_status; +}; + +enum npcm_sgpio_reg { + READ_DATA, + WRITE_DATA, + EVENT_CFG, + EVENT_STS, +}; + +static const struct npcm_sgpio_bank npcm_sgpio_banks[] = { + { + .wdata_reg = 0x00, + .rdata_reg = 0x08, + .event_config = 0x10, + .event_status = 0x20, + }, + { + .wdata_reg = 0x01, + .rdata_reg = 0x09, + .event_config = 0x12, + .event_status = 0x21, + }, + { + .wdata_reg = 0x02, + .rdata_reg = 0x0a, + .event_config = 0x14, + .event_status = 0x22, + }, + { + .wdata_reg = 0x03, + .rdata_reg = 0x0b, + .event_config = 0x16, + .event_status = 0x23, + }, + { + .wdata_reg = 0x04, + .rdata_reg = 0x0c, + .event_config = 0x18, + .event_status = 0x24, + }, + { + .wdata_reg = 0x05, + .rdata_reg = 0x0d, + .event_config = 0x1a, + .event_status = 0x25, + }, + { + .wdata_reg = 0x06, + .rdata_reg = 0x0e, + .event_config = 0x1c, + .event_status = 0x26, + }, + { + .wdata_reg = 0x07, + .rdata_reg = 0x0f, + .event_config = 0x1e, + .event_status = 0x27, + }, + +}; + +static void __iomem *bank_reg(struct npcm_sgpio *gpio, + const struct npcm_sgpio_bank *bank, + const enum npcm_sgpio_reg reg) +{ + switch (reg) { + case READ_DATA: + return gpio->base + bank->rdata_reg; + case WRITE_DATA: + return gpio->base + bank->wdata_reg; + case EVENT_CFG: + return gpio->base + bank->event_config; + case EVENT_STS: + return gpio->base + bank->event_status; + default: + /* actually if code runs to here, it's an error case */ + dev_WARN(true, "Getting here is an error condition"); + } + return 0; +} + +static const struct npcm_sgpio_bank *offset_to_bank(unsigned int offset) +{ + unsigned int bank = GPIO_BANK(offset); + + return &npcm_sgpio_banks[bank]; +} + +static void irqd_to_npcm_sgpio_data(struct irq_data *d, + struct npcm_sgpio **gpio, + const struct npcm_sgpio_bank **bank, + u8 *bit, unsigned int *offset) +{ + struct npcm_sgpio *internal; + + *offset = irqd_to_hwirq(d); + internal = irq_data_get_irq_chip_data(d); + + *gpio = internal; + *offset -= internal->nout_sgpio; + *bank = offset_to_bank(*offset); + *bit = GPIO_BIT(*offset); +} + +static int npcm_sgpio_init_port(struct npcm_sgpio *gpio) +{ + u8 in_port, out_port, set_port, reg; + + in_port = GPIO_BANK(gpio->nin_sgpio); + if (GPIO_BIT(gpio->nin_sgpio) > 0) + in_port += 1; + + out_port = GPIO_BANK(gpio->nout_sgpio); + if (GPIO_BIT(gpio->nout_sgpio) > 0) + out_port += 1; + + gpio->in_port = in_port; + gpio->out_port = out_port; + set_port = ((out_port & NPCM_IOXCFG2_PORT) << 4) | (in_port & NPCM_IOXCFG2_PORT); + iowrite8(set_port, gpio->base + NPCM_IOXCFG2); + + reg = ioread8(gpio->base + NPCM_IOXCFG2); + + return reg == set_port ? 0 : -EINVAL; + +} + +static int npcm_sgpio_dir_in(struct gpio_chip *gc, unsigned int offset) +{ + struct npcm_sgpio *gpio = gpiochip_get_data(gc); + + return offset < gpio->nout_sgpio ? -EINVAL : 0; + +} + +static int npcm_sgpio_dir_out(struct gpio_chip *gc, unsigned int offset, int val) +{ + struct npcm_sgpio *gpio = gpiochip_get_data(gc); + + gc->set(gc, offset, val); + + return 0; + +} + +static int npcm_sgpio_get_direction(struct gpio_chip *gc, unsigned int offset) +{ + struct npcm_sgpio *gpio = gpiochip_get_data(gc); + + if (offset > gpio->chip.ngpio) + return -EINVAL; + + if (offset < gpio->nout_sgpio) + return GPIO_LINE_DIRECTION_OUT; + + return GPIO_LINE_DIRECTION_IN; +} + +static void npcm_sgpio_set(struct gpio_chip *gc, unsigned int offset, int val) +{ + struct npcm_sgpio *gpio = gpiochip_get_data(gc); + const struct npcm_sgpio_bank *bank = offset_to_bank(offset); + void __iomem *addr; + u8 reg = 0; + + addr = bank_reg(gpio, bank, WRITE_DATA); + reg = ioread8(addr); + + if (val) + reg |= (val << GPIO_BIT(offset)); + else + reg &= ~(1 << GPIO_BIT(offset)); + + iowrite8(reg, addr); +} + +static int npcm_sgpio_get(struct gpio_chip *gc, unsigned int offset) +{ + struct npcm_sgpio *gpio = gpiochip_get_data(gc); + const struct npcm_sgpio_bank *bank; + void __iomem *addr; + u8 reg; + int dir; + + dir = npcm_sgpio_get_direction(gc, offset); + if (dir == 0) { + bank = offset_to_bank(offset); + + addr = bank_reg(gpio, bank, WRITE_DATA); + reg = ioread8(addr); + reg = !!(reg & GPIO_BIT(offset)); + } else { + offset -= gpio->nout_sgpio; + bank = offset_to_bank(offset); + + addr = bank_reg(gpio, bank, READ_DATA); + reg = ioread8(addr); + reg = !!(reg & GPIO_BIT(offset)); + } + + return reg; +} + +static void npcm_sgpio_setup_enable(struct npcm_sgpio *gpio, bool enable) +{ + u8 reg = 0; + + reg = ioread8(gpio->base + NPCM_IOXCTS); + reg = reg & ~NPCM_IOXCTS_RD_MODE; + reg = reg | NPCM_IOXCTS_RD_MODE_PERIODIC; + + if (enable) { + reg |= NPCM_IOXCTS_IOXIF_EN; + iowrite8(reg, gpio->base + NPCM_IOXCTS); + } else { + reg &= ~NPCM_IOXCTS_IOXIF_EN; + iowrite8(reg, gpio->base + NPCM_IOXCTS); + } +} + +static int npcm_sgpio_setup_clk(struct npcm_sgpio *gpio, + const struct npcm_clk_cfg *clk_cfg) +{ + unsigned long apb_freq; + u32 val; + u8 tmp; + int i; + + apb_freq = clk_get_rate(gpio->pclk); + tmp = ioread8(gpio->base + NPCM_IOXCFG1) & ~NPCM_IOXCFG1_SFT_CLK; + + for (i = 0; i < clk_cfg->cfg_opt; i++) { + val = apb_freq / clk_cfg->sft_clk[i]; + if ((NPCM_CLK_MHZ < val) && (i != 0) ) { + iowrite8(clk_cfg->clk_sel[i-1] | tmp, gpio->base + NPCM_IOXCFG1); + return 0; + } else if (i == (clk_cfg->cfg_opt-1) && (NPCM_CLK_MHZ > val)) { + iowrite8(clk_cfg->clk_sel[i] | tmp, gpio->base + NPCM_IOXCFG1); + return 0; + } + } + + return -EINVAL; +} + +static void npcm_sgpio_irq_init_valid_mask(struct gpio_chip *gc, + unsigned long *valid_mask, unsigned int ngpios) +{ + struct npcm_sgpio *gpio = gpiochip_get_data(gc); + int n = gpio->nin_sgpio; + + /* input GPIOs in the high range */ + bitmap_set(valid_mask, gpio->nout_sgpio, n); + bitmap_clear(valid_mask, 0, gpio->nout_sgpio); +} + +static void npcm_sgpio_irq_set_mask(struct irq_data *d, bool set) +{ + const struct npcm_sgpio_bank *bank; + struct npcm_sgpio *gpio; + unsigned long flags; + void __iomem *addr; + unsigned int offset; + u16 reg, type; + u8 bit; + + irqd_to_npcm_sgpio_data(d, &gpio, &bank, &bit, &offset); + addr = bank_reg(gpio, bank, EVENT_CFG); + + raw_spin_lock_irqsave(&gpio->lock, flags); + + npcm_sgpio_setup_enable(gpio, false); + + reg = ioread16(addr); + if (set) { + reg &= ~(NPCM_IXOEVCFG_MASK << (bit * 2)); + } else { + type = gpio->int_type[offset]; + reg |= (type << (bit * 2)); + } + + iowrite16(reg, addr); + + npcm_sgpio_setup_enable(gpio, true); + + addr = bank_reg(gpio, bank, EVENT_STS); + reg = ioread8(addr); + reg |= BIT(bit); + iowrite8(reg, addr); + + raw_spin_unlock_irqrestore(&gpio->lock, flags); +} + +static void npcm_sgpio_irq_ack(struct irq_data *d) +{ + const struct npcm_sgpio_bank *bank; + struct npcm_sgpio *gpio; + unsigned long flags; + void __iomem *status_addr; + unsigned int offset; + u8 bit; + + irqd_to_npcm_sgpio_data(d, &gpio, &bank, &bit, &offset); + status_addr = bank_reg(gpio, bank, EVENT_STS); + raw_spin_lock_irqsave(&gpio->lock, flags); + iowrite8(BIT(bit), status_addr); + raw_spin_unlock_irqrestore(&gpio->lock, flags); +} + +static void npcm_sgpio_irq_mask(struct irq_data *d) +{ + npcm_sgpio_irq_set_mask(d, true); +} + +static void npcm_sgpio_irq_unmask(struct irq_data *d) +{ + npcm_sgpio_irq_set_mask(d, false); +} + +static int npcm_sgpio_set_type(struct irq_data *d, unsigned int type) +{ + const struct npcm_sgpio_bank *bank; + irq_flow_handler_t handler; + struct npcm_sgpio *gpio; + unsigned long flags; + void __iomem *addr; + unsigned int offset; + u16 reg, val; + u8 bit; + + irqd_to_npcm_sgpio_data(d, &gpio, &bank, &bit, &offset); + + switch (type & IRQ_TYPE_SENSE_MASK) { + case IRQ_TYPE_EDGE_BOTH: + val = NPCM_IXOEVCFG_BOTH; + handler = handle_edge_irq; + break; + case IRQ_TYPE_EDGE_RISING: + val = NPCM_IXOEVCFG_RISING; + handler = handle_edge_irq; + break; + case IRQ_TYPE_EDGE_FALLING: + val = NPCM_IXOEVCFG_FALLING; + handler = handle_edge_irq; + break; + case IRQ_TYPE_LEVEL_HIGH: + val = NPCM_IXOEVCFG_RISING; + handler = handle_level_irq; + break; + case IRQ_TYPE_LEVEL_LOW: + val = NPCM_IXOEVCFG_FALLING; + handler = handle_level_irq; + break; + default: + return -EINVAL; + } + + gpio->int_type[offset] = val; + + raw_spin_lock_irqsave(&gpio->lock, flags); + npcm_sgpio_setup_enable(gpio, false); + addr = bank_reg(gpio, bank, EVENT_CFG); + reg = ioread16(addr); + + reg |= (val << (bit * 2)); + + iowrite16(reg, addr); + npcm_sgpio_setup_enable(gpio, true); + raw_spin_unlock_irqrestore(&gpio->lock, flags); + + irq_set_handler_locked(d, handler); + + return 0; +} + +static void npcm_sgpio_irq_handler(struct irq_desc *desc) +{ + struct gpio_chip *gc = irq_desc_get_handler_data(desc); + struct irq_chip *ic = irq_desc_get_chip(desc); + struct npcm_sgpio *gpio = gpiochip_get_data(gc); + unsigned int i, j, girq; + unsigned long reg; + + chained_irq_enter(ic, desc); + + for (i = 0; i < ARRAY_SIZE(npcm_sgpio_banks); i++) { + const struct npcm_sgpio_bank *bank = &npcm_sgpio_banks[i]; + + reg = ioread8(bank_reg(gpio, bank, EVENT_STS)); + for_each_set_bit(j, ®, 8) { + girq = irq_find_mapping(gc->irq.domain, i * 8 + gpio->nout_sgpio + j); + generic_handle_irq(girq); + } + } + + chained_irq_exit(ic, desc); +} + +static const struct irq_chip sgpio_irq_chip = { + .name = "sgpio-irq", + .irq_ack = npcm_sgpio_irq_ack, + .irq_mask = npcm_sgpio_irq_mask, + .irq_unmask = npcm_sgpio_irq_unmask, + .irq_set_type = npcm_sgpio_set_type, + .flags = IRQCHIP_IMMUTABLE | IRQCHIP_MASK_ON_SUSPEND, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + +static int npcm_sgpio_setup_irqs(struct npcm_sgpio *gpio, + struct platform_device *pdev) +{ + int rc, i; + struct gpio_irq_chip *irq; + + rc = platform_get_irq(pdev, 0); + if (rc < 0) + return rc; + + gpio->irq = rc; + + npcm_sgpio_setup_enable(gpio, false); + + /* Disable IRQ and clear Interrupt status registers for all SGPIO Pins. */ + for (i = 0; i < ARRAY_SIZE(npcm_sgpio_banks); i++) { + const struct npcm_sgpio_bank *bank = &npcm_sgpio_banks[i]; + + iowrite16(0x0000, bank_reg(gpio, bank, EVENT_CFG)); + iowrite8(0xff, bank_reg(gpio, bank, EVENT_STS)); + } + + irq = &gpio->chip.irq; + gpio_irq_chip_set_chip(irq, &sgpio_irq_chip); + irq->init_valid_mask = npcm_sgpio_irq_init_valid_mask; + irq->handler = handle_bad_irq; + irq->default_type = IRQ_TYPE_NONE; + irq->parent_handler = npcm_sgpio_irq_handler; + irq->parent_handler_data = gpio; + irq->parents = &gpio->irq; + irq->num_parents = 1; + + return 0; +} + +static const unsigned int npcm750_SFT_CLK[] = { + 1024, 32, 8, 4, 3, 2, +}; + +static const unsigned int npcm750_CLK_SEL[] = { + 0x00, 0x05, 0x07, 0x0C, 0x0D, 0x0E, +}; + +static const unsigned int npcm845_SFT_CLK[] = { + 1024, 32, 16, 8, 4, +}; + +static const unsigned int npcm845_CLK_SEL[] = { + 0x00, 0x05, 0x06, 0x07, 0x0C, +}; + +static const struct npcm_clk_cfg npcm750_sgpio_pdata = { + .sft_clk = npcm750_SFT_CLK, + .clk_sel = npcm750_CLK_SEL, + .cfg_opt = 6, +}; + +static const struct npcm_clk_cfg npcm845_sgpio_pdata = { + .sft_clk = npcm845_SFT_CLK, + .clk_sel = npcm845_CLK_SEL, + .cfg_opt = 5, +}; + +static const struct of_device_id npcm_sgpio_of_table[] = { + { .compatible = "nuvoton,npcm750-sgpio", .data = &npcm750_sgpio_pdata, }, + { .compatible = "nuvoton,npcm845-sgpio", .data = &npcm845_sgpio_pdata, }, + {} +}; +MODULE_DEVICE_TABLE(of, npcm_sgpio_of_table); + +static int npcm_sgpio_probe(struct platform_device *pdev) +{ + struct npcm_sgpio *gpio; + const struct npcm_clk_cfg *clk_cfg; + int rc; + u32 nin_gpios, nout_gpios; + + gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); + if (!gpio) + return -ENOMEM; + + gpio->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(gpio->base)) + return PTR_ERR(gpio->base); + + clk_cfg = device_get_match_data(&pdev->dev); + if (!clk_cfg) + return -EINVAL; + + rc = device_property_read_u32(&pdev->dev, "nuvoton,input-ngpios", &nin_gpios); + if (rc < 0) + return dev_err_probe(&pdev->dev, rc, "Could not read ngpios property\n"); + + rc = device_property_read_u32(&pdev->dev, "nuvoton,output-ngpios", &nout_gpios); + if (rc < 0) + return dev_err_probe(&pdev->dev, rc, "Could not read ngpios property\n"); + + gpio->nin_sgpio = nin_gpios; + gpio->nout_sgpio = nout_gpios; + if (gpio->nin_sgpio > MAX_NR_HW_SGPIO || gpio->nout_sgpio > MAX_NR_HW_SGPIO) { + dev_err(&pdev->dev, "Number of GPIOs exceeds the maximum of %d: input: %d output: %d\n", + MAX_NR_HW_SGPIO, nin_gpios, nout_gpios); + return -EINVAL; + } + + gpio->pclk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(gpio->pclk)) { + dev_err(&pdev->dev, "Could not get pclk\n"); + return PTR_ERR(gpio->pclk); + } + + rc = npcm_sgpio_setup_clk(gpio, clk_cfg); + if (rc < 0) + return dev_err_probe(&pdev->dev, rc, "Failed to setup clock\n"); + + raw_spin_lock_init(&gpio->lock); + gpio->chip.parent = &pdev->dev; + gpio->chip.ngpio = gpio->nin_sgpio + gpio->nout_sgpio; + gpio->chip.direction_input = npcm_sgpio_dir_in; + gpio->chip.direction_output = npcm_sgpio_dir_out; + gpio->chip.get_direction = npcm_sgpio_get_direction; + gpio->chip.get = npcm_sgpio_get; + gpio->chip.set = npcm_sgpio_set; + gpio->chip.label = dev_name(&pdev->dev); + gpio->chip.base = -1; + + rc = npcm_sgpio_init_port(gpio); + if (rc < 0) + return rc; + + rc = npcm_sgpio_setup_irqs(gpio, pdev); + if (rc < 0) + return rc; + + rc = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio); + if (rc < 0) + return rc; + + npcm_sgpio_setup_enable(gpio, true); + + return 0; +} + +static struct platform_driver npcm_sgpio_driver = { + .driver = { + .name = KBUILD_MODNAME, + .of_match_table = npcm_sgpio_of_table, + }, + .probe = npcm_sgpio_probe, +}; +module_platform_driver(npcm_sgpio_driver); + +MODULE_AUTHOR("Jim Liu "); +MODULE_AUTHOR("Joseph Liu "); +MODULE_DESCRIPTION("Nuvoton NPCM Serial GPIO Driver"); +MODULE_LICENSE("GPL v2");