From patchwork Fri Mar 29 18:54:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Abel Vesa X-Patchwork-Id: 13610937 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 0B8D0C6FD1F for ; Fri, 29 Mar 2024 18:55:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References :Message-Id:Content-Transfer-Encoding:Content-Type: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=e0l9XqgR5rgZt/McZ1+LYeV2+Ae3g0xUIEFWoqdq9PI=; b=bKE354SKiGkfYoRVkhk4ZNZ8bG ZvtYLgXC8JByXSqwnTgX0HwyqlfvmLicCgj6PpXbtz5ys3Sh98YXndQsNBfxUVN+ey2sBLau+GDBi r32Fv6LFiPvhuFsRK6n6GoPurW7iPA0hxp8LajVsBIPRpQsJzEiDgVAny8p4wXcmLsGZgr0ozJAmN ii8utc6Aop8lHtLFKdosGgFT8RNuZE1tRRaFhaUXOK1s62Dm/6FTsnHWME2apdecAl8oLIxv1Ajp0 v7qf6yx0hlAGyfRf0dQ/tkOOCi2wrWzaiVDAYGzonOe9u5GGGg/mjyhd/GW99GIUV7S9ewL9BHJ4v 8D0qcdzw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rqHNW-00000001f8K-1xyp; Fri, 29 Mar 2024 18:55:02 +0000 Received: from mail-ej1-x635.google.com ([2a00:1450:4864:20::635]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1rqHNH-00000001evo-21H4 for linux-mediatek@lists.infradead.org; Fri, 29 Mar 2024 18:54:50 +0000 Received: by mail-ej1-x635.google.com with SMTP id a640c23a62f3a-a4e0e3ef357so304268266b.2 for ; Fri, 29 Mar 2024 11:54:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1711738484; x=1712343284; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=e0l9XqgR5rgZt/McZ1+LYeV2+Ae3g0xUIEFWoqdq9PI=; b=giJxJjYsWGXCT0NNyElkyYyx6GLpqnUugiETqUrAcMK57o8POrlJO4g/G1jn6Jd+Nb OZuvMfYvLD/E1IDkBLCF3V1jFAKQVbkMFUFzD4bJIqL21tfVW7oiJ9GD4osVCvlXBC4N pu0syRz930La5Xw4BG77Y7oZZWfAJqVbosaLnb2KNLfo1J9p24wrQsT4iM7MupOhirHQ /YjZssmMX4MSM/NciM+Jd/bEccP6GMmgi2tFrY5T5p4zWVOiKMEgN8nqjFw2Vio6c4Pi NWreV7RDMqE7G2p44On9AN7lkbI4ZKiMg24uf+wfeC08ud0XfntwZi6+CH6I5S4iZkIA 7v5w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711738484; x=1712343284; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=e0l9XqgR5rgZt/McZ1+LYeV2+Ae3g0xUIEFWoqdq9PI=; b=HQLFpX9OwoB5quEtuuqv9YQ/+aI2YttRo3UWEkg59w15RczD2rQaYfYX8cj6LRcKdB i2lsG2yF5rJPGDgtjVRVPTZQTOdeHumHitJiOiIf5wp7XTMC3hZt5wgzBL+cfCOf2IkO 8pb9HxI6VXKyXOIzyKEZdLqlUckPAMbEYSQvUKd3oSvDPUbn0SxOYl4HctMAo+HjXsQO pjS4iKgs6sQZz48FgEM+mr2tfVZemBUmb1Uyc/8/pIx54N8WdoGWy/A94CjAadcIRUwI LwFTdVUCy/W1XkGBwCxPs4ObqTzR21SUd2oXf45X7aXCcQ5FDCz5aC0d/HeeDhp4eOHm 4MlQ== X-Forwarded-Encrypted: i=1; AJvYcCUz2XjGwkLIa++3oBS5xlBVu3CXVf1XA3jqv2tRz5OHP5bHAFccmRS1HFnwIeKkmSA2s+TGX3DI/whi7w7rTeMEwg7GRyk7gaD8ykFRZsi/N6ea X-Gm-Message-State: AOJu0Yz5o9R4FPp2vHC8NUCFYELZaZNrgVyUht8w0eVgyGfyGprTrq8q SGdelJTeUsua8DWdsiuJ4cZmZBsgSYSyJnJNnZyIWudSCXo8E5tyJSRghUBJ/+Y= X-Google-Smtp-Source: AGHT+IEvez3gnbfE1h985nyrZbf3lwtS5MK1xcBVKx0GUJnsoq87hfeTZGXxgOag0cR9v/4ebdQxYw== X-Received: by 2002:a17:907:9877:b0:a4e:1c3d:89a0 with SMTP id ko23-20020a170907987700b00a4e1c3d89a0mr2367909ejc.4.1711738484378; Fri, 29 Mar 2024 11:54:44 -0700 (PDT) Received: from [127.0.1.1] ([79.114.172.194]) by smtp.gmail.com with ESMTPSA id gl20-20020a170906e0d400b00a46c39e6a47sm2235618ejb.148.2024.03.29.11.54.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 Mar 2024 11:54:44 -0700 (PDT) From: Abel Vesa Date: Fri, 29 Mar 2024 20:54:18 +0200 Subject: [PATCH v7 1/6] dt-bindings: spmi: Add X1E80100 SPMI PMIC ARB schema MIME-Version: 1.0 Message-Id: <20240329-spmi-multi-master-support-v7-1-7b902824246c@linaro.org> References: <20240329-spmi-multi-master-support-v7-0-7b902824246c@linaro.org> In-Reply-To: <20240329-spmi-multi-master-support-v7-0-7b902824246c@linaro.org> To: Stephen Boyd , Matthias Brugger , Bjorn Andersson , Konrad Dybcio , Dmitry Baryshkov , Neil Armstrong , AngeloGioacchino Del Regno , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Srini Kandagatla , Johan Hovold , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-arm-msm@vger.kernel.org, linux-mediatek@lists.infradead.org, devicetree@vger.kernel.org, Abel Vesa , Krzysztof Kozlowski X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4280; i=abel.vesa@linaro.org; h=from:subject:message-id; bh=H2L6hk3BSbGZWXsaMqnOwDhN0rNiIn1lAFbUz+5zVTU=; b=owEBbQKS/ZANAwAKARtfRMkAlRVWAcsmYgBmBw5p2QmwCkKqbzyOMMbpOWoF0qvc0ARyq+X+6 7dr0j/S0MGJAjMEAAEKAB0WIQRO8+4RTnqPKsqn0bgbX0TJAJUVVgUCZgcOaQAKCRAbX0TJAJUV VszXEAC7xyiA34AfEV+TDkvZPPpgeAtVDPvwKYKFPF3hrkY3F0SNCyutBXWPsZ7dENoGccze8U0 7kCiz7fwqH0tnQV4rqcWaKO7cbWzczKlGSlxVVDYElSZ8a0zGf9WxWwzYDOKMkJjad9+eD+Xzex VZKu9Utt06TL/e8lfdjrAInA7X/Ck+RrxxzU7XVz5bKQE5WeKpQf5gth7xUsvcNBcfdk0sRq5iK VflDiQ2y44YfO7Xuj/CLbOtUeORzhUHJl4L45OHG2UoFE+oNpD2jCSFWHLf3d01gnINHUYDrSJz 47qnj+g26WRZwhTI/I/C/s+cYbpDvlP/rrmTy9fE7a5El/h69oOXt4ScbzOU9SyDIqJE8N9yZTs 95P5VyxPlfzlykS13ZWttrlVU7s5Lf4m5Vr0j3JRTp5AmW2sZAf+UOwr1xhnMzzkVh/UM1UVe4e LbkV130Tk5QEfBSg++abtl+qjr0cogYZfYGAxH2GMVOQcTFEqVohDWou6hxuGxXtSA45hP+vzoV 3wn41LNj9CsGULuLON5/HvbBG0VZCHBS40ZP01hft0uBYPsXXksiSn18m/NLojuBXl130tp8oQF W3eFMnDjO+bGm4CwZsmi4lKQYHk6UJJLeyzSh0qKzO0mDFPcDKYlOcuxWONbDlTkDpQuAbblx3Y 9QJj0ZUb51A+sGQ== X-Developer-Key: i=abel.vesa@linaro.org; a=openpgp; fpr=6AFF162D57F4223A8770EF5AF7BF214136F41FAE X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240329_115447_571861_486BFE84 X-CRM114-Status: GOOD ( 12.62 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org Add dedicated schema for X1E80100 PMIC ARB (v7) as it allows multiple buses by declaring them as child nodes. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Abel Vesa --- .../bindings/spmi/qcom,x1e80100-spmi-pmic-arb.yaml | 136 +++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/Documentation/devicetree/bindings/spmi/qcom,x1e80100-spmi-pmic-arb.yaml b/Documentation/devicetree/bindings/spmi/qcom,x1e80100-spmi-pmic-arb.yaml new file mode 100644 index 000000000000..f32a7ae33b4b --- /dev/null +++ b/Documentation/devicetree/bindings/spmi/qcom,x1e80100-spmi-pmic-arb.yaml @@ -0,0 +1,136 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spmi/qcom,x1e80100-spmi-pmic-arb.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm X1E80100 SPMI Controller (PMIC Arbiter v7) + +maintainers: + - Stephen Boyd + +description: | + The X1E80100 SPMI PMIC Arbiter implements HW version 7 and it's an SPMI + controller with wrapping arbitration logic to allow for multiple on-chip + devices to control up to 2 SPMI separate buses. + + The PMIC Arbiter can also act as an interrupt controller, providing interrupts + to slave devices. + +properties: + compatible: + const: qcom,x1e80100-spmi-pmic-arb + + reg: + items: + - description: core registers + - description: tx-channel per virtual slave regosters + - description: rx-channel (called observer) per virtual slave registers + + reg-names: + items: + - const: core + - const: chnls + - const: obsrvr + + ranges: true + + '#address-cells': + const: 2 + + '#size-cells': + const: 2 + + qcom,ee: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 5 + description: > + indicates the active Execution Environment identifier + + qcom,channel: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 5 + description: > + which of the PMIC Arb provided channels to use for accesses + +patternProperties: + "^spmi@[a-f0-9]+$": + type: object + $ref: /schemas/spmi/spmi.yaml + unevaluatedProperties: false + + properties: + reg: + items: + - description: configuration registers + - description: interrupt controller registers + + reg-names: + items: + - const: cnfg + - const: intr + + interrupts: + maxItems: 1 + + interrupt-names: + const: periph_irq + + interrupt-controller: true + + '#interrupt-cells': + const: 4 + description: | + cell 1: slave ID for the requested interrupt (0-15) + cell 2: peripheral ID for requested interrupt (0-255) + cell 3: the requested peripheral interrupt (0-7) + cell 4: interrupt flags indicating level-sense information, + as defined in dt-bindings/interrupt-controller/irq.h + +required: + - compatible + - reg-names + - qcom,ee + - qcom,channel + +additionalProperties: false + +examples: + - | + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + spmi: arbiter@c400000 { + compatible = "qcom,x1e80100-spmi-pmic-arb"; + reg = <0 0x0c400000 0 0x3000>, + <0 0x0c500000 0 0x4000000>, + <0 0x0c440000 0 0x80000>; + reg-names = "core", "chnls", "obsrvr"; + + qcom,ee = <0>; + qcom,channel = <0>; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + spmi_bus0: spmi@c42d000 { + reg = <0 0x0c42d000 0 0x4000>, + <0 0x0c4c0000 0 0x10000>; + reg-names = "cnfg", "intr"; + + interrupt-names = "periph_irq"; + interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>; + interrupt-controller; + #interrupt-cells = <4>; + + #address-cells = <2>; + #size-cells = <0>; + }; + }; + }; From patchwork Fri Mar 29 18:54:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Abel Vesa X-Patchwork-Id: 13610938 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 E3681CD1283 for ; Fri, 29 Mar 2024 18:55:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References :Message-Id:Content-Transfer-Encoding:Content-Type: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=8lYudh1XGipLZp45Ed9irT2kjTBzp7nX6WUMRhG9/PM=; b=TTH26Xs2Tl0KP2RgRNVaVHBkYy 2x87jDlUKM/rf14wHhfQWGH2RaA/9qrWDvzSgKxXTdAM+H0G839fA/+PJYtbF4ZdmxyxWyO3b1V8J EVpRU0avgFmFXkKYe67oT2hliBW/gnTOxoQ5dtN4w5B7hvwbu4Ex4V3VGHcopFNlYSkmEcYrvJY2o jih3GNAHdD69tMPkmurr31zAQrK+8KoTcaeEgznzqyf86rP7Bn1DZ3Bkk13PiWK09PR05xwYxovXq yCOw7V9vdPoMoG9NtmOguqvGrrjMxLDkEzPv4E/PneHGVdgxbBdEx7IoYWkpeT9OnKHTymtgkeQvI Nznee08g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rqHNf-00000001fDO-1yIw; Fri, 29 Mar 2024 18:55:11 +0000 Received: from mail-lj1-x230.google.com ([2a00:1450:4864:20::230]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1rqHNJ-00000001ewp-1bH5 for linux-mediatek@lists.infradead.org; Fri, 29 Mar 2024 18:54:50 +0000 Received: by mail-lj1-x230.google.com with SMTP id 38308e7fff4ca-2d6fd3cfaceso28333721fa.3 for ; Fri, 29 Mar 2024 11:54:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1711738486; x=1712343286; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=8lYudh1XGipLZp45Ed9irT2kjTBzp7nX6WUMRhG9/PM=; b=j6KpiYvLXErtpDNrlq+Fm3W8nr809B5P7XPkSnAdi00AWeRE6knwfMbJdZOTyjc+m8 QObcgBP8mhkTB+/fJNWOzeZxfrxL8qG1zqrYUm63zoYd4XJIC2aaoh3pr/zHRpUEAFjU KrSqGx4BLlvGDL9fCzEEkKN+cwD7Pkz0j2BPmFAWwNaZPX2ZyHj+rvGwOwjUBshS6IpM x97vq/ijBH2KLYR+XDttrGBWnzJu+w0zS9JCbSoKP/ZBSEkhtep8h/cbso73nm5zl9aq pqS0nTXaZz0tO146FXvzfzSQJ3zQTvXON4B/IChXcwAiDU6DsqEbwPDxpFJOv22diQCV Kk3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711738486; x=1712343286; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=8lYudh1XGipLZp45Ed9irT2kjTBzp7nX6WUMRhG9/PM=; b=VOEBxcsaQa16ZJZKnCJ92PLiBmxR/Kln3bfUULbtYysqquFmqa2hgzmZpD1Sgf+Fj8 lsc/1tzzLE899b7I3bnHj17+rW0vTaabyXcGBTIvFeUuuB5CTCmBbMUejKUpsyi/VuQj +1Ni2eUl0inaW8ruRUyFbPl0Ic834MHHE5N2b1Ep4nfh0Pf/5nYsF+XeBh/DQs38m+Fl yrEJnd0E6QnzG/JRizPeBpa5jntJvNLFB52HJgY0+01LAjzRp6Hf1U0WRrri+JcbU+c5 4TV7KdSFW5BOvoq9fbFdfUtevMghylUldt8uqNTwfhCyV6T4j2La3HOBLnY/kYpHD1ub FHJg== X-Forwarded-Encrypted: i=1; AJvYcCVRuS9BN30wdMtN008Li4i7Nwlhj+AL3a0wQp26ttYEBCk7GoZIf5SEcQibAUyr1NajywjfL8d6FHqaaJxnmp104M9sj9603Pj/qhK21kUo9268 X-Gm-Message-State: AOJu0Yzl8CRtHNEri1iZDXx/AbMF2pPRDfW0bYLwf4nZOtKJ1fE3Sl95 yDaw4Ws49ZrcvVMWQrU3CRntTMh+ZnARfAqxzxpYlH9sINR/rhLcTzCll4KyNNQ= X-Google-Smtp-Source: AGHT+IFLq2zPNZAQWIXV2oGHh7AXsnxXyYm+kF2F9Y8m5wIc8iL/MpNSFstxnipVIzw2JZJ8+OEiLQ== X-Received: by 2002:a05:6512:3f2:b0:513:cc18:d4c6 with SMTP id n18-20020a05651203f200b00513cc18d4c6mr2423772lfq.41.1711738485916; Fri, 29 Mar 2024 11:54:45 -0700 (PDT) Received: from [127.0.1.1] ([79.114.172.194]) by smtp.gmail.com with ESMTPSA id gl20-20020a170906e0d400b00a46c39e6a47sm2235618ejb.148.2024.03.29.11.54.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 Mar 2024 11:54:45 -0700 (PDT) From: Abel Vesa Date: Fri, 29 Mar 2024 20:54:19 +0200 Subject: [PATCH v7 2/6] dt-bindings: spmi: Deprecate qcom,bus-id MIME-Version: 1.0 Message-Id: <20240329-spmi-multi-master-support-v7-2-7b902824246c@linaro.org> References: <20240329-spmi-multi-master-support-v7-0-7b902824246c@linaro.org> In-Reply-To: <20240329-spmi-multi-master-support-v7-0-7b902824246c@linaro.org> To: Stephen Boyd , Matthias Brugger , Bjorn Andersson , Konrad Dybcio , Dmitry Baryshkov , Neil Armstrong , AngeloGioacchino Del Regno , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Srini Kandagatla , Johan Hovold , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-arm-msm@vger.kernel.org, linux-mediatek@lists.infradead.org, devicetree@vger.kernel.org, Abel Vesa , Krzysztof Kozlowski X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1023; i=abel.vesa@linaro.org; h=from:subject:message-id; bh=f1k2/XtnKKT0QabjDTtzy+0Tu+D0+1BkiYHMuQzuNWI=; b=owEBbQKS/ZANAwAKARtfRMkAlRVWAcsmYgBmBw5rmBF1a6Kayn0McPPhO9Vili8LVVjwUHVTA Ms6jQpU9aiJAjMEAAEKAB0WIQRO8+4RTnqPKsqn0bgbX0TJAJUVVgUCZgcOawAKCRAbX0TJAJUV VjcfD/9TlUMe8f+3fPhLYasDGg8g/v36up5C2ABrJX8El4US2PozU/+1trcDJU52ZXplM4CiawA ebRTCjQ+vB4Ca8MN2XWbaCeeUu/0ecjmS/48HSrnRhphCoIXCTe8AWUKwO+R8VBRnRKPGdJg7u1 kUTzgSclc9W0ThCgx8xXEUV4sR8Tk0Q4sOc7GPORWd55rBjAN8r5L3LhO8USw5A2TUc6wWI0iDX X9RxsdMBXyS7Ej4+jQcZlxhEru5zKQtjEVyagVLEh6WhnSB07uU6hY6+zG/yREFm4fEeu5JDQgO Cn/rgajjrkX7d2sF4aCY3gLZqWaF0shIGI1IgUPGsvLLRCTfvkM8ZXgfGeGQWhA6BW0fcMGbHe9 BjU8rqrXvV9N91vAhN+3AyijyFcQQ4n3Ge2RUtdhQ1OcmfsBK3Bp3mjdStQqUm8+RGtuVTCqTaD 8eN6QIaPVMZ4ZRoI1o9pQI+5RiLBIBQF24jf/BVM6cWEEQM5mMB9L69QErcsdy42FgybYoMsVXq Ujoxjut03zTyn+h5XZvGSUyYHuHl8EFH440/peAFjMmc0wT41HSBd+64w5OSoTq9c02w7skXyfP p+hVjyJFiBh/zpj9kAC8WqX62nGSxOfM6JXauUagiuw+tN/XDGXda/Zl2jmRQEgRjSXuV4xCmXf nDUfN/EHg2aDOaw== X-Developer-Key: i=abel.vesa@linaro.org; a=openpgp; fpr=6AFF162D57F4223A8770EF5AF7BF214136F41FAE X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240329_115449_537566_BC8272BE X-CRM114-Status: UNSURE ( 8.43 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org As it is optional and no platform is actually using the secondary bus, deprecate the qcom,bus-id property. For newer platforms that implement SPMI PMIC ARB v7 in HW, the X1E80100 approach should be used. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Abel Vesa --- Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml index f983b4af6db9..51daf1b847a9 100644 --- a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml +++ b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml @@ -92,6 +92,7 @@ properties: description: > SPMI bus instance. only applicable to PMIC arbiter version 7 and beyond. Supported values, 0 = primary bus, 1 = secondary bus + deprecated: true required: - compatible From patchwork Fri Mar 29 18:54:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Abel Vesa X-Patchwork-Id: 13610940 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 8B70AC6FD1F for ; Fri, 29 Mar 2024 18:55:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References :Message-Id:Content-Transfer-Encoding:Content-Type: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=7oA0fmKcMGpa77tBwzlw1ahRCKvmpIwJPYwf28NyUZ4=; b=Lo4A3aAq7toPvq3wvjDu9lxMM8 aX9FaLdnPe6/fz7f6BstaqIlYDtWNd3vOKh+WBF2tW8jyJ3m7lEOzz1gkpLqpPJA8h3WMLmHK+vcU ENI5Keyb59UP9Kf00V6a5ZbIvqUhWpqCyQVlGTqGNaLqTiJE8yLuHAMQz7i9cs2bBd+z6R8c+mgf+ 1Y68mfELn0ewLSQoQ1BaAh2f34FZKFeDJaLbdOTzeu+c8Ev1JPxiMvs0W/1AIbEdxFguJv+7LhDD4 L9ecVLc8haJoIyvB1HxX1KDtQAanR9y34f6zWUjyp/8bo2atMTsnOB3rRO7usaYw4ef+WMerPRxGL IgOGTTvw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rqHO2-00000001fR0-3w88; Fri, 29 Mar 2024 18:55:34 +0000 Received: from mail-lf1-x135.google.com ([2a00:1450:4864:20::135]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1rqHNL-00000001exu-01WY for linux-mediatek@lists.infradead.org; Fri, 29 Mar 2024 18:54:55 +0000 Received: by mail-lf1-x135.google.com with SMTP id 2adb3069b0e04-513e134f73aso2804267e87.2 for ; Fri, 29 Mar 2024 11:54:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1711738488; x=1712343288; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=7oA0fmKcMGpa77tBwzlw1ahRCKvmpIwJPYwf28NyUZ4=; b=UZ07gtpQof8ONub0DBLSj+txZOgLanCh3KeNpayn4UbsMD8fe42YbeHjwzFuYiS4kP gIrqE+4R2/gs1rp1z4CpA75t2lwOqBIqvRxHIAiwUDeSCk7c/B8cmLI4NxO9xEl+dJCK Ftd2E6LhtrT8uikeq3dT3Tr0JzWwCZf0lYpFuy8ggxHyeLdmCLDbHPlT7zBsXyXk3ph1 +M5ROBMjJnEyXyHwA4d90ylW4XVWbKZPpAMjDCuobC5GQhWH4st6tUfzlP4yzDQPpiTs Hi6btVcAIA6x/nkV4vrxYLfZqE/x8qnIG8DqTPmfl8yEmHwafFwUWrRIzejiWLCox68U mfvg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711738488; x=1712343288; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=7oA0fmKcMGpa77tBwzlw1ahRCKvmpIwJPYwf28NyUZ4=; b=Nu+RCMWCB37V/cBezXC9zCyXHTtTNRZXorXVxOZRK6CM6sEnOynDDwwEZH88302vWv EQMicuFpy+ChWt90EB3NCIB9olweRDoYXrBTzIBoQ6VUExxLyAMRcu1SnXej57bu0lJF uc5fmlVBk+ox00rW4yXeag6611wRZU06/8KAAx6SSibr3t6hec3TrEH74PLVk84xHgjr v2xZQV86Y+Tgana5lB5/lHb/8Bl2gH6u8Ux5CkK+7bX7iLrNnX5st7n0k2rM0YTvg1oa QwQ1FYuBE8xbB6VGxrrnQGlbWPhFa8oxUCZif0YG76heHkbPeagSbru2ZeWie20JYZML n7uw== X-Forwarded-Encrypted: i=1; AJvYcCVJPpslAoc1KaUAV/mfA9dbgOsrEHExBOIPWm/31UK04SuRFZQiDP8qsxurm/AaNWi/MP+7IPFRWjTwXY9KfpTurUmOoTnGf7ejSkmu8hn+/Pi1 X-Gm-Message-State: AOJu0Yx1JUpz3tDlkKwhkNiCi5/ti/PyuVQgkPJmZUgbcr0e1Wlo8GLR LTkWO/y0+FHABX0SeYVjOl1VRWBk8ylddnNSG3fu8ZnLuW/YKYQcmYwSVA2XRNk= X-Google-Smtp-Source: AGHT+IFq1RCJXoIsvu9fBFRl2uicKEKEcc7wyo0P0s8ze/0jMPmikOK4LFecCqtE61O2E0i0Ov2Tlw== X-Received: by 2002:ac2:5de9:0:b0:515:d196:6d4c with SMTP id z9-20020ac25de9000000b00515d1966d4cmr1561650lfq.34.1711738487458; Fri, 29 Mar 2024 11:54:47 -0700 (PDT) Received: from [127.0.1.1] ([79.114.172.194]) by smtp.gmail.com with ESMTPSA id gl20-20020a170906e0d400b00a46c39e6a47sm2235618ejb.148.2024.03.29.11.54.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 Mar 2024 11:54:47 -0700 (PDT) From: Abel Vesa Date: Fri, 29 Mar 2024 20:54:20 +0200 Subject: [PATCH v7 3/6] spmi: pmic-arb: Make the APID init a version operation MIME-Version: 1.0 Message-Id: <20240329-spmi-multi-master-support-v7-3-7b902824246c@linaro.org> References: <20240329-spmi-multi-master-support-v7-0-7b902824246c@linaro.org> In-Reply-To: <20240329-spmi-multi-master-support-v7-0-7b902824246c@linaro.org> To: Stephen Boyd , Matthias Brugger , Bjorn Andersson , Konrad Dybcio , Dmitry Baryshkov , Neil Armstrong , AngeloGioacchino Del Regno , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Srini Kandagatla , Johan Hovold , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-arm-msm@vger.kernel.org, linux-mediatek@lists.infradead.org, devicetree@vger.kernel.org, Abel Vesa X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=10831; i=abel.vesa@linaro.org; h=from:subject:message-id; bh=xUhXxEB1TSjaY+70YZslQBzXRf4SXFhFlW0PDrTOM4E=; b=owEBbQKS/ZANAwAKARtfRMkAlRVWAcsmYgBmBw5s23qOSsIxlAnplYOuCgDQz8cJDmpB/PyCi PAF5WUaBCGJAjMEAAEKAB0WIQRO8+4RTnqPKsqn0bgbX0TJAJUVVgUCZgcObAAKCRAbX0TJAJUV Vq5gEACC7/hCIYxDB6ozwcnTIt+YcvsR4u8feKZTImGAZfanhwVlKHpluVysT7WIQLIwYOsTE45 Gis1DGOpXfx4sSKRGQ1OXY0tAhh80VKsi9b482xv5cHM6ukZuQwbfYtZil/Mge3kNkHPHxGNC3E EtEI6Riyj2a/foe4mWPm5/O6YT6dkZxbnIoh4B2H2lxTOuQF4/neBS9XFHZ0t+MxzI3Rd9J6Fgb +FoMVYj9xM/AurtIcvQOShUwIq06hnSVtohEGZAu2IsOj+7BH0+5Oya4wx4OnxLiRykhV/hNEOY E2sJD9OQj4RnwqsZabGaYdRPD71PvIQnHRyXmK17DPOmegZHILkigV7EBiVsMict7THn/X9F4wW Agx1rX9isa6qDXvu2yxlzGM10w439gHA2HkNU9ArCxJAuwaQiR6IVxEg2270q1K2E3R/YILMl/B /j0A5gbVv3BdPcqUvVSfKozCzB1LXOPQvFZTDZsqVctCwnQMrvVLDpcpoPbV354DRF8s988BPts HWkpz6OvQpRkwJXaFPR6prwh5l2Cj8Y+CDEmi1vuypbElcyhAvLLE0Yvy3O8/nkvGMOD3MoHmiK VSoyMDUaMB2RDbpFAQnGTpfVkC6SFYfo1mdvs+xgNVHJ3b8BtLASX+p5vfZhFSkDD9HTXF1sEF9 rMxtdpVLnhllnOA== X-Developer-Key: i=abel.vesa@linaro.org; a=openpgp; fpr=6AFF162D57F4223A8770EF5AF7BF214136F41FAE X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240329_115451_286956_921659F8 X-CRM114-Status: GOOD ( 20.34 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org Rather than using conditionals in probe function, add the APID init as a version specific operation. Due to v7, which supports multiple buses, pass on the bus index to be used for sorting out the apid base and count. Signed-off-by: Abel Vesa Reviewed-by: Neil Armstrong --- drivers/spmi/spmi-pmic-arb.c | 199 +++++++++++++++++++++++++++---------------- 1 file changed, 124 insertions(+), 75 deletions(-) diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index 9ed1180fe31f..38fed8a585fe 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -183,6 +183,7 @@ struct spmi_pmic_arb { * struct pmic_arb_ver_ops - version dependent functionality. * * @ver_str: version string. + * @init_apid: finds the apid base and count * @ppid_to_apid: finds the apid for a given ppid. * @non_data_cmd: on v1 issues an spmi non-data command. * on v2 no HW support, returns -EOPNOTSUPP. @@ -202,6 +203,7 @@ struct spmi_pmic_arb { */ struct pmic_arb_ver_ops { const char *ver_str; + int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index); int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid); /* spmi commands (read_cmd, write_cmd, cmd) functionality */ int (*offset)(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr, @@ -942,6 +944,38 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain, return 0; } +static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb) +{ + /* + * Initialize max_apid/min_apid to the opposite bounds, during + * the irq domain translation, we are sure to update these + */ + pmic_arb->max_apid = 0; + pmic_arb->min_apid = pmic_arb->max_periphs - 1; + + return 0; +} + +static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index) +{ + u32 *mapping_table; + + if (index) { + dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n", + index); + return -EINVAL; + } + + mapping_table = devm_kcalloc(&pmic_arb->spmic->dev, pmic_arb->max_periphs, + sizeof(*mapping_table), GFP_KERNEL); + if (!mapping_table) + return -ENOMEM; + + pmic_arb->mapping_table = mapping_table; + + return pmic_arb_init_apid_min_max(pmic_arb); +} + static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid) { u32 *mapping_table = pmic_arb->mapping_table; @@ -1144,6 +1178,40 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr, return 0x1000 * pmic_arb->ee + 0x8000 * apid; } +static int pmic_arb_init_apid_v5(struct spmi_pmic_arb *pmic_arb, int index) +{ + int ret; + + if (index) { + dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n", + index); + return -EINVAL; + } + + pmic_arb->base_apid = 0; + pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) & + PMIC_ARB_FEATURES_PERIPH_MASK; + + if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) { + dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n", + pmic_arb->base_apid + pmic_arb->apid_count); + return -EINVAL; + } + + ret = pmic_arb_init_apid_min_max(pmic_arb); + if (ret) + return ret; + + ret = pmic_arb_read_apid_map_v5(pmic_arb); + if (ret) { + dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n", + ret); + return ret; + } + + return 0; +} + /* * v5 offset per ee and per apid for observer channels and per apid for * read/write channels. @@ -1178,6 +1246,49 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr, return offset; } +/* + * Only v7 supports 2 buses. Each bus will get a different apid count, read + * from different registers. + */ +static int pmic_arb_init_apid_v7(struct spmi_pmic_arb *pmic_arb, int index) +{ + int ret; + + if (index == 0) { + pmic_arb->base_apid = 0; + pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) & + PMIC_ARB_FEATURES_PERIPH_MASK; + } else if (index == 1) { + pmic_arb->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) & + PMIC_ARB_FEATURES_PERIPH_MASK; + pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) & + PMIC_ARB_FEATURES_PERIPH_MASK; + } else { + dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n", + index); + return -EINVAL; + } + + if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) { + dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n", + pmic_arb->base_apid + pmic_arb->apid_count); + return -EINVAL; + } + + ret = pmic_arb_init_apid_min_max(pmic_arb); + if (ret) + return ret; + + ret = pmic_arb_read_apid_map_v5(pmic_arb); + if (ret) { + dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n", + ret); + return ret; + } + + return 0; +} + /* * v7 offset per ee and per apid for observer channels and per apid for * read/write channels. @@ -1358,6 +1469,7 @@ pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n) static const struct pmic_arb_ver_ops pmic_arb_v1 = { .ver_str = "v1", + .init_apid = pmic_arb_init_apid_v1, .ppid_to_apid = pmic_arb_ppid_to_apid_v1, .non_data_cmd = pmic_arb_non_data_cmd_v1, .offset = pmic_arb_offset_v1, @@ -1372,6 +1484,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = { static const struct pmic_arb_ver_ops pmic_arb_v2 = { .ver_str = "v2", + .init_apid = pmic_arb_init_apid_v1, .ppid_to_apid = pmic_arb_ppid_to_apid_v2, .non_data_cmd = pmic_arb_non_data_cmd_v2, .offset = pmic_arb_offset_v2, @@ -1386,6 +1499,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = { static const struct pmic_arb_ver_ops pmic_arb_v3 = { .ver_str = "v3", + .init_apid = pmic_arb_init_apid_v1, .ppid_to_apid = pmic_arb_ppid_to_apid_v2, .non_data_cmd = pmic_arb_non_data_cmd_v2, .offset = pmic_arb_offset_v2, @@ -1400,6 +1514,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v3 = { static const struct pmic_arb_ver_ops pmic_arb_v5 = { .ver_str = "v5", + .init_apid = pmic_arb_init_apid_v5, .ppid_to_apid = pmic_arb_ppid_to_apid_v5, .non_data_cmd = pmic_arb_non_data_cmd_v2, .offset = pmic_arb_offset_v5, @@ -1414,6 +1529,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = { static const struct pmic_arb_ver_ops pmic_arb_v7 = { .ver_str = "v7", + .init_apid = pmic_arb_init_apid_v7, .ppid_to_apid = pmic_arb_ppid_to_apid_v5, .non_data_cmd = pmic_arb_non_data_cmd_v2, .offset = pmic_arb_offset_v7, @@ -1439,7 +1555,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) struct spmi_controller *ctrl; struct resource *res; void __iomem *core; - u32 *mapping_table; u32 channel, ee, hw_ver; int err; @@ -1467,12 +1582,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) pmic_arb->core_size = resource_size(res); - pmic_arb->ppid_to_apid = devm_kcalloc(&ctrl->dev, PMIC_ARB_MAX_PPID, - sizeof(*pmic_arb->ppid_to_apid), - GFP_KERNEL); - if (!pmic_arb->ppid_to_apid) - return -ENOMEM; - hw_ver = readl_relaxed(core + PMIC_ARB_VERSION); if (hw_ver < PMIC_ARB_VERSION_V2_MIN) { @@ -1506,58 +1615,17 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) return PTR_ERR(pmic_arb->wr_base); } - pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS; + dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n", + pmic_arb->ver_ops->ver_str, hw_ver); - if (hw_ver >= PMIC_ARB_VERSION_V7_MIN) { + if (hw_ver < PMIC_ARB_VERSION_V7_MIN) + pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS; + else pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7; - /* Optional property for v7: */ - of_property_read_u32(pdev->dev.of_node, "qcom,bus-id", - &pmic_arb->bus_instance); - if (pmic_arb->bus_instance > 1) { - dev_err(&pdev->dev, "invalid bus instance (%u) specified\n", - pmic_arb->bus_instance); - return -EINVAL; - } - - if (pmic_arb->bus_instance == 0) { - pmic_arb->base_apid = 0; - pmic_arb->apid_count = - readl_relaxed(core + PMIC_ARB_FEATURES) & - PMIC_ARB_FEATURES_PERIPH_MASK; - } else { - pmic_arb->base_apid = - readl_relaxed(core + PMIC_ARB_FEATURES) & - PMIC_ARB_FEATURES_PERIPH_MASK; - pmic_arb->apid_count = - readl_relaxed(core + PMIC_ARB_FEATURES1) & - PMIC_ARB_FEATURES_PERIPH_MASK; - } - if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) { - dev_err(&pdev->dev, "Unsupported APID count %d detected\n", - pmic_arb->base_apid + pmic_arb->apid_count); - return -EINVAL; - } - } else if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) { - pmic_arb->base_apid = 0; - pmic_arb->apid_count = readl_relaxed(core + PMIC_ARB_FEATURES) & - PMIC_ARB_FEATURES_PERIPH_MASK; - - if (pmic_arb->apid_count > pmic_arb->max_periphs) { - dev_err(&pdev->dev, "Unsupported APID count %d detected\n", - pmic_arb->apid_count); - return -EINVAL; - } - } - - pmic_arb->apid_data = devm_kcalloc(&ctrl->dev, pmic_arb->max_periphs, - sizeof(*pmic_arb->apid_data), - GFP_KERNEL); - if (!pmic_arb->apid_data) - return -ENOMEM; - - dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n", - pmic_arb->ver_ops->ver_str, hw_ver); + err = pmic_arb->ver_ops->init_apid(pmic_arb, 0); + if (err) + return err; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr"); pmic_arb->intr = devm_ioremap_resource(&ctrl->dev, res); @@ -1599,16 +1667,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) } pmic_arb->ee = ee; - mapping_table = devm_kcalloc(&ctrl->dev, pmic_arb->max_periphs, - sizeof(*mapping_table), GFP_KERNEL); - if (!mapping_table) - return -ENOMEM; - - pmic_arb->mapping_table = mapping_table; - /* Initialize max_apid/min_apid to the opposite bounds, during - * the irq domain translation, we are sure to update these */ - pmic_arb->max_apid = 0; - pmic_arb->min_apid = pmic_arb->max_periphs - 1; platform_set_drvdata(pdev, ctrl); raw_spin_lock_init(&pmic_arb->lock); @@ -1617,15 +1675,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) ctrl->read_cmd = pmic_arb_read_cmd; ctrl->write_cmd = pmic_arb_write_cmd; - if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) { - err = pmic_arb_read_apid_map_v5(pmic_arb); - if (err) { - dev_err(&pdev->dev, "could not read APID->PPID mapping table, rc= %d\n", - err); - return err; - } - } - dev_dbg(&pdev->dev, "adding irq domain\n"); pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node, &pmic_arb_irq_domain_ops, pmic_arb); From patchwork Fri Mar 29 18:54:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Abel Vesa X-Patchwork-Id: 13610939 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 68302CD1283 for ; Fri, 29 Mar 2024 18:55:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References :Message-Id:Content-Transfer-Encoding:Content-Type: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=cuRJarbec7jfhNmRygSPVxuNpYaNSltHxT1UdGqVad0=; b=V84IOSqGOA7tjCk0byTdgw8+TN 06irHuqSyvpJYHJXAUTzDV9w4o0E7G8O6L3x+Rzm7b9NVa2eZtnmgFG1yiz5dZTWus5AAHQA2If5u xPnvWJ9B+oH3YL5utTLrQpftZJxinhtF0NBEtiiMLf0hcyHNZ6GemN5vfukyrqgNKTEX+CHKLYG8b UpWvtFi9lsWHs9iLhkuA2O60ZdnkfF2DxbtaD5Jcdq6DvAeB6ckrZr29rjgGwJeQifgcKGEstx2bC MxuMESrQxT35JWKGqpEwdU0SfRTB9BGxexqHHImu1hVSFGcyH+8dNZlls3DLYuTtO7R7EMrNTGyHV i3csRLcg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rqHNs-00000001fLd-3hnx; Fri, 29 Mar 2024 18:55:24 +0000 Received: from mail-ed1-x52c.google.com ([2a00:1450:4864:20::52c]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1rqHNM-00000001eyw-01Jq for linux-mediatek@lists.infradead.org; Fri, 29 Mar 2024 18:54:54 +0000 Received: by mail-ed1-x52c.google.com with SMTP id 4fb4d7f45d1cf-56b8e4f38a2so2815870a12.3 for ; Fri, 29 Mar 2024 11:54:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1711738489; x=1712343289; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=cuRJarbec7jfhNmRygSPVxuNpYaNSltHxT1UdGqVad0=; b=Rq7O7yxVGzKF21k9NoU9czNVEq9z7bg6qQze1SMPCT6SxtfG8N9V4LmS1hyiAcZU1N 7LGmMG0gBxKhTPnXzsTeIZhggH9DFrJxc8BCQwRRYWXAHee3gHOkjNXEKkLOosHC0aXK +h09o8xpi5EJjapotcVW40WUDguxizuvN9DR75VnDR8OoQQq2Je4QkQKMMvHP0RUDtYP owxY1LO8IYg9DilPezmU3JXdpA+4hr8WoQIKqovHiPI7xZ5d6p+hb0z/2nZm+FqLSCx7 qRhd3mqznRUAbJTAxGa4ZTBGPzZC0vFmuTi9ZtyopMP7GPXJ4cbMRQ5qBXHtr7madDC6 dldw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711738489; x=1712343289; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=cuRJarbec7jfhNmRygSPVxuNpYaNSltHxT1UdGqVad0=; b=pbbzKNWLpgVSJVy9H5TPKN4iUS285AgLaD1nV8uY/8bjaV1S5B9O4bm5SVCI+KzWjG wtwBEcswyjbVV+rsaGxjjFvSz4f1yg6gHqhhkR30RE+XRlBRx1Cax/Pw80UENYQIUthv KJtkQPAxZ4WmKK2H3NycVX/D38zb7aIgzjy9lUr1bBA+m8otABHtYKMlZlsFG7fwmij+ CvBckzH+nFsSMoQoNe/zu3qfq2XANrNrz4z7wp8eX1eULfLWFjDVW1zVur90jNo1G0ZC oA6aTXn2j808NvirLpqkC8MjrCTT/4B69Ey7WNHab+Eo7lAVqIdq4dOO5l6uRh8U2xzz TQ/A== X-Forwarded-Encrypted: i=1; AJvYcCXwDZp7jaTeZjRZGX/1mce/B+ySINdy522BJPimibpRHwr1GDSOzCa09vXxW/zFMj7jhIg+WCT/BavMyo2aQAS0AoY/5it7HD/nISMd6CUFNlQb X-Gm-Message-State: AOJu0YyfxEAAMHDaKYoCadvvN/xMrEPi/DCdTB/SY8EN0NE/p/C7iFKF 7tjW0F0iMaQQYWYTaL8wtoSAdEpfZ6PQ+8k1d1dW7GmTQBi7LI7fVoYOw0IpTbI= X-Google-Smtp-Source: AGHT+IEkfmLlGD/keMPoNisXIDK6Cw079oLjkff8JBeQJYIy5gvktwlheJQX7F2EEstW1KRY8l+CIg== X-Received: by 2002:a17:906:751:b0:a47:533b:10 with SMTP id z17-20020a170906075100b00a47533b0010mr1949297ejb.62.1711738488994; Fri, 29 Mar 2024 11:54:48 -0700 (PDT) Received: from [127.0.1.1] ([79.114.172.194]) by smtp.gmail.com with ESMTPSA id gl20-20020a170906e0d400b00a46c39e6a47sm2235618ejb.148.2024.03.29.11.54.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 Mar 2024 11:54:48 -0700 (PDT) From: Abel Vesa Date: Fri, 29 Mar 2024 20:54:21 +0200 Subject: [PATCH v7 4/6] spmi: pmic-arb: Make core resources acquiring a version operation MIME-Version: 1.0 Message-Id: <20240329-spmi-multi-master-support-v7-4-7b902824246c@linaro.org> References: <20240329-spmi-multi-master-support-v7-0-7b902824246c@linaro.org> In-Reply-To: <20240329-spmi-multi-master-support-v7-0-7b902824246c@linaro.org> To: Stephen Boyd , Matthias Brugger , Bjorn Andersson , Konrad Dybcio , Dmitry Baryshkov , Neil Armstrong , AngeloGioacchino Del Regno , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Srini Kandagatla , Johan Hovold , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-arm-msm@vger.kernel.org, linux-mediatek@lists.infradead.org, devicetree@vger.kernel.org, Abel Vesa X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=7896; i=abel.vesa@linaro.org; h=from:subject:message-id; bh=vH5adHP1EAvzF8O0o4HxU8svaRA6gdvZ4ICXbaOtPTA=; b=owEBbQKS/ZANAwAKARtfRMkAlRVWAcsmYgBmBw5tutK7rEXCC1CRUOAszcBVUrqbBgrxWDwTx 4pE8Zr4o6WJAjMEAAEKAB0WIQRO8+4RTnqPKsqn0bgbX0TJAJUVVgUCZgcObQAKCRAbX0TJAJUV VnNOEACAoQukHuH8idc09I21aE5kr9LtY48y1QJrzGLO4KLU6bIy2mBX5B+84hdzsSSF6lFpDmZ +yxQRqPS9jBoxPPQEVlR8qgQo0xQDfK/UfY2yS6GyZz42YHsf7yB9qNbBIYX/HBMCeNnio9e44c i+7IYQroFIReNs5KcdVU8kuH8IlQnP83/tNr6dqOfRs2T/WXf3y8zSF060+mu0NxJwR7JwLBSGW AWGz3lBEgrlbICGxbCIuBj32sCtdsWbuz95ZB267ZvNIKgzsVkkSZqz8Og4pyysGgCw4Zprd/mA DjjlDSe3zVEmK72aseNprriaGqm3aPaDtVZhyS3UccFeI2y2AV9g/kx8AXAGsJGRNUYL3Of538B bJhyJi4PxrAMfL5Fmi3LgxRnD5nEaRnLET3OkHONpZrDYvBJE68CW0Tusl91VKjBvdimDerkH+I SYCuIv4Yq+RHNSD53TG0CTmxbbDCjbL60MJOyVESy1uNk+BJzktucQwM/g6aYi1lw7jpwQojAkl VVl+CiGSIaWhNhPK1bGm3EKwSRNfHpZ2r9BVp/t+AFgTQAEJvxUhws1ji3yRDTreI2kv+vokmWy XMjQdJL8Bc9xAWJLBUg1urnXAuQE7wpxGdxCeZu1DZ7+Ln1Clh9QavcRfcXelfuGw/T7G/b4x2Z zIVrpzA5sDkZpaA== X-Developer-Key: i=abel.vesa@linaro.org; a=openpgp; fpr=6AFF162D57F4223A8770EF5AF7BF214136F41FAE X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240329_115452_250423_E1732B6F X-CRM114-Status: GOOD ( 19.47 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org Rather than setting up the core, obsrv and chnls in probe by using version specific conditionals, add a dedicated "get_core_resources" version specific op and move the acquiring in there. Since there are no current users of the second bus yet, drop the comment about why devm_platform_ioremap_resource can't be used in case of "core", as it is not applicable anymore. Don't switch to devm_platform_ioremap_resource though as we need to keep track of core size. Reviewed-by: Neil Armstrong Signed-off-by: Abel Vesa --- drivers/spmi/spmi-pmic-arb.c | 113 +++++++++++++++++++++++++++---------------- 1 file changed, 70 insertions(+), 43 deletions(-) diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index 38fed8a585fe..188252bfb95f 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -203,6 +203,7 @@ struct spmi_pmic_arb { */ struct pmic_arb_ver_ops { const char *ver_str; + int (*get_core_resources)(struct platform_device *pdev, void __iomem *core); int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index); int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid); /* spmi commands (read_cmd, write_cmd, cmd) functionality */ @@ -956,6 +957,19 @@ static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb) return 0; } +static int pmic_arb_get_core_resources_v1(struct platform_device *pdev, + void __iomem *core) +{ + struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev); + + pmic_arb->wr_base = core; + pmic_arb->rd_base = core; + + pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS; + + return 0; +} + static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index) { u32 *mapping_table; @@ -1063,6 +1077,33 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid) return apid; } +static int pmic_arb_get_obsrvr_chnls_v2(struct platform_device *pdev) +{ + struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev); + + pmic_arb->rd_base = devm_platform_ioremap_resource_byname(pdev, "obsrvr"); + if (IS_ERR(pmic_arb->rd_base)) + return PTR_ERR(pmic_arb->rd_base); + + pmic_arb->wr_base = devm_platform_ioremap_resource_byname(pdev, "chnls"); + if (IS_ERR(pmic_arb->wr_base)) + return PTR_ERR(pmic_arb->wr_base); + + return 0; +} + +static int pmic_arb_get_core_resources_v2(struct platform_device *pdev, + void __iomem *core) +{ + struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev); + + pmic_arb->core = core; + + pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS; + + return pmic_arb_get_obsrvr_chnls_v2(pdev); +} + static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb *pmic_arb, u16 ppid) { u16 apid_valid; @@ -1246,6 +1287,18 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr, return offset; } +static int pmic_arb_get_core_resources_v7(struct platform_device *pdev, + void __iomem *core) +{ + struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev); + + pmic_arb->core = core; + + pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7; + + return pmic_arb_get_obsrvr_chnls_v2(pdev); +} + /* * Only v7 supports 2 buses. Each bus will get a different apid count, read * from different registers. @@ -1469,6 +1522,7 @@ pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n) static const struct pmic_arb_ver_ops pmic_arb_v1 = { .ver_str = "v1", + .get_core_resources = pmic_arb_get_core_resources_v1, .init_apid = pmic_arb_init_apid_v1, .ppid_to_apid = pmic_arb_ppid_to_apid_v1, .non_data_cmd = pmic_arb_non_data_cmd_v1, @@ -1484,6 +1538,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = { static const struct pmic_arb_ver_ops pmic_arb_v2 = { .ver_str = "v2", + .get_core_resources = pmic_arb_get_core_resources_v2, .init_apid = pmic_arb_init_apid_v1, .ppid_to_apid = pmic_arb_ppid_to_apid_v2, .non_data_cmd = pmic_arb_non_data_cmd_v2, @@ -1499,6 +1554,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = { static const struct pmic_arb_ver_ops pmic_arb_v3 = { .ver_str = "v3", + .get_core_resources = pmic_arb_get_core_resources_v2, .init_apid = pmic_arb_init_apid_v1, .ppid_to_apid = pmic_arb_ppid_to_apid_v2, .non_data_cmd = pmic_arb_non_data_cmd_v2, @@ -1514,6 +1570,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v3 = { static const struct pmic_arb_ver_ops pmic_arb_v5 = { .ver_str = "v5", + .get_core_resources = pmic_arb_get_core_resources_v2, .init_apid = pmic_arb_init_apid_v5, .ppid_to_apid = pmic_arb_ppid_to_apid_v5, .non_data_cmd = pmic_arb_non_data_cmd_v2, @@ -1529,6 +1586,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = { static const struct pmic_arb_ver_ops pmic_arb_v7 = { .ver_str = "v7", + .get_core_resources = pmic_arb_get_core_resources_v7, .init_apid = pmic_arb_init_apid_v7, .ppid_to_apid = pmic_arb_ppid_to_apid_v5, .non_data_cmd = pmic_arb_non_data_cmd_v2, @@ -1565,16 +1623,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) pmic_arb = spmi_controller_get_drvdata(ctrl); pmic_arb->spmic = ctrl; - /* - * Please don't replace this with devm_platform_ioremap_resource() or - * devm_ioremap_resource(). These both result in a call to - * devm_request_mem_region() which prevents multiple mappings of this - * register address range. SoCs with PMIC arbiter v7 may define two - * arbiter devices, for the two physical SPMI interfaces, which share - * some register address ranges (i.e. "core", "obsrvr", and "chnls"). - * Ensure that both devices probe successfully by calling devm_ioremap() - * which does not result in a devm_request_mem_region() call. - */ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core"); core = devm_ioremap(&ctrl->dev, res->start, resource_size(res)); if (IS_ERR(core)) @@ -1584,44 +1632,23 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) hw_ver = readl_relaxed(core + PMIC_ARB_VERSION); - if (hw_ver < PMIC_ARB_VERSION_V2_MIN) { + if (hw_ver < PMIC_ARB_VERSION_V2_MIN) pmic_arb->ver_ops = &pmic_arb_v1; - pmic_arb->wr_base = core; - pmic_arb->rd_base = core; - } else { - pmic_arb->core = core; - - if (hw_ver < PMIC_ARB_VERSION_V3_MIN) - pmic_arb->ver_ops = &pmic_arb_v2; - else if (hw_ver < PMIC_ARB_VERSION_V5_MIN) - pmic_arb->ver_ops = &pmic_arb_v3; - else if (hw_ver < PMIC_ARB_VERSION_V7_MIN) - pmic_arb->ver_ops = &pmic_arb_v5; - else - pmic_arb->ver_ops = &pmic_arb_v7; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "obsrvr"); - pmic_arb->rd_base = devm_ioremap(&ctrl->dev, res->start, - resource_size(res)); - if (IS_ERR(pmic_arb->rd_base)) - return PTR_ERR(pmic_arb->rd_base); - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "chnls"); - pmic_arb->wr_base = devm_ioremap(&ctrl->dev, res->start, - resource_size(res)); - if (IS_ERR(pmic_arb->wr_base)) - return PTR_ERR(pmic_arb->wr_base); - } + else if (hw_ver < PMIC_ARB_VERSION_V3_MIN) + pmic_arb->ver_ops = &pmic_arb_v2; + else if (hw_ver < PMIC_ARB_VERSION_V5_MIN) + pmic_arb->ver_ops = &pmic_arb_v3; + else if (hw_ver < PMIC_ARB_VERSION_V7_MIN) + pmic_arb->ver_ops = &pmic_arb_v5; + else + pmic_arb->ver_ops = &pmic_arb_v7; dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n", pmic_arb->ver_ops->ver_str, hw_ver); - if (hw_ver < PMIC_ARB_VERSION_V7_MIN) - pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS; - else - pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7; + err = pmic_arb->ver_ops->get_core_resources(pdev, core); + if (err) + return err; err = pmic_arb->ver_ops->init_apid(pmic_arb, 0); if (err) From patchwork Fri Mar 29 18:54:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Abel Vesa X-Patchwork-Id: 13610942 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 78ECCCD1283 for ; Fri, 29 Mar 2024 18:56:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References :Message-Id:Content-Transfer-Encoding:Content-Type: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=ifCptV9/MxyB7LI01o2oOSmzdjNZ/k7NlPx/q/YTg3Y=; b=kt6+sK5RPtlcYJEs+72RiM6C01 e4sBv1+m6Z4eNx88S9U9vbgJFlb2h0PDqWb+WChLZBGxKsJyi7Z5Ocwz0beIkqqzRyYr1+meX4l5D XXXvK61eLvmujiaXt9s/zmXlvMxYcI9u9Cu/Oi+hIyP+j4u392r4c+qk/Q4v5daw69IvqkUAFlsHk SktwiffbGmnrASLKPh08eIrB7cTKHm4cJB94NgqU6vk7i7TGt8JANI1ij41KlrtsSECE6MDj11Jbq ZhslLwHM9dON4JMfzFdEx2EVLUDwvSDZJGpPDbHVucXpppAQoc0xP4ltP4TYDFbHn3E3bYgDzqS3c uOJX4cNg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rqHOT-00000001fgq-3wpa; Fri, 29 Mar 2024 18:56:01 +0000 Received: from mail-lj1-x232.google.com ([2a00:1450:4864:20::232]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1rqHNO-00000001f0p-0L8h for linux-mediatek@lists.infradead.org; Fri, 29 Mar 2024 18:55:02 +0000 Received: by mail-lj1-x232.google.com with SMTP id 38308e7fff4ca-2d718efedb2so14732031fa.0 for ; Fri, 29 Mar 2024 11:54:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1711738491; x=1712343291; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=ifCptV9/MxyB7LI01o2oOSmzdjNZ/k7NlPx/q/YTg3Y=; b=i8POOqaVndesf6m9wJI4fduKgK45rsWNLsGjkvoYhtUgk5JaLJEg0HhNGPjTn9KMDq DLRy12BPRpQBTuMZoaugWHf2qw/s+efjPC4tbmPBZZxfGrMWpNtKZ/wRlO6WQGDtRZSZ XxL7yoRGTYgCeUTd39vJFXHgN868GNx6ypL0eYoje09jssoYb7FPMXaolZaqrSqWAPxf 7/Yk/RKki2le2deRBwjhPFVFPhxq8hgOnKpnubJyPOUBmP2w/VrAO7SW//iR/1X55hJT YqF1ubE12HrfwxIf2DAmxTnkjhvbW+dojIGTNIWCF3LmjgxJZA68/wPsK3HgGHftwaNC zP3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711738491; x=1712343291; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ifCptV9/MxyB7LI01o2oOSmzdjNZ/k7NlPx/q/YTg3Y=; b=ekgMcNBoRsnDTzSStKQnTYulXVMzKFjill3u+sNRG71PykmbllMF28B0sWrIWpa8EW HRPt9luWXpUHiLMWAaeA7QtirFnaXtS2wrJGWuSHUTmoD1+s3IH9yzT2BXK5zRyoWpDe rq1XN63dPerGH/q9oP9OCNdnTVrrznOiPpTYqHG0W/slyj8uJQ5rkwBiYS43sIQ7hMUB 8VIv2yPPCrRpQ3PKaXKWNA1PYIVzx5aN2huQCljfV4Q/F877pIkuKYIP1v3x04go6la0 bJba9il3EMJADLxk53TDynt4SVG/tmGjhFLkt3E9LHc7R2sVYebDHBZIDu+xcROziPQd JGFQ== X-Forwarded-Encrypted: i=1; AJvYcCWZKHjMY/6CGsSUPTMBP4QBn8HkmmMAp6Q1np2JiWxYjHCEGolQ/H4C9krwKAVrlFwwie2DdrUpbgZ2kr1ouFRz+ygnGyw3TRUI4yfnRgdv7fVN X-Gm-Message-State: AOJu0YxoBZPNTluyN+UJqCDQceyzxH7D7O0wzwa4ljzTHYDLBMq0811c quASnNxlEdW20Fc9MvYDAaQFnQ3COVK5xDzke5pI45mlsYuBlzterTFe1226ots= X-Google-Smtp-Source: AGHT+IExw5D1zYpMEt1AzJ0mip+20EPv8td5+lyh0XnCAnWi6TbKnTwlZr3pwDU5ChGyS8n3PbnPDw== X-Received: by 2002:a2e:b5d4:0:b0:2d7:11bf:1fc4 with SMTP id g20-20020a2eb5d4000000b002d711bf1fc4mr2191867ljn.42.1711738490633; Fri, 29 Mar 2024 11:54:50 -0700 (PDT) Received: from [127.0.1.1] ([79.114.172.194]) by smtp.gmail.com with ESMTPSA id gl20-20020a170906e0d400b00a46c39e6a47sm2235618ejb.148.2024.03.29.11.54.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 Mar 2024 11:54:50 -0700 (PDT) From: Abel Vesa Date: Fri, 29 Mar 2024 20:54:22 +0200 Subject: [PATCH v7 5/6] spmi: pmic-arb: Register controller for bus instead of arbiter MIME-Version: 1.0 Message-Id: <20240329-spmi-multi-master-support-v7-5-7b902824246c@linaro.org> References: <20240329-spmi-multi-master-support-v7-0-7b902824246c@linaro.org> In-Reply-To: <20240329-spmi-multi-master-support-v7-0-7b902824246c@linaro.org> To: Stephen Boyd , Matthias Brugger , Bjorn Andersson , Konrad Dybcio , Dmitry Baryshkov , Neil Armstrong , AngeloGioacchino Del Regno , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Srini Kandagatla , Johan Hovold , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-arm-msm@vger.kernel.org, linux-mediatek@lists.infradead.org, devicetree@vger.kernel.org, Abel Vesa X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=52722; i=abel.vesa@linaro.org; h=from:subject:message-id; bh=G+JhetTGZFbzAHCU6QzMOrRvzTcRV0rORkrOy+h3wfA=; b=owEBbQKS/ZANAwAKARtfRMkAlRVWAcsmYgBmBw5vgvrWJNTOAr9ueMGURPntzwX9On28VPnW/ AUCZlcVcneJAjMEAAEKAB0WIQRO8+4RTnqPKsqn0bgbX0TJAJUVVgUCZgcObwAKCRAbX0TJAJUV VoXdD/9ykMVhEFrEF+SBF8ZaLEyrPI/KL1cxit2rlm+9QV7BqRDUT5c6DW4sh3zwBZds2v1Ca21 7AVJppz4Hu4IKpQUZHz2PSX18CRcY9OfVIW3alhyEjR86XnrXdUoDKrOI7OTCgkAIEOE4ZRO3W+ JWZd/AXoyLYNrCdmDcynBux/pZP2ph2gz8d9r+2KUmlNlXUHoZRAgL2t+b6fbWSBoPYyT8sbAHB dUQGjClBDZUttWpdzjr++uDp4ad1QkvHbeAkx56bq5wQtUyNNzjX0J/HRvj55FyViZvHb9br7Ie pq6yJ4HB8G3rNzFHHYWwwIl3Tfla1O7doSELZ69JiAZ8CBVie5Hi7ZgF3G5bvqK1TjCbKl5FL1P RZWfXQsidmT6FuanBtcy7sckCApEuOmSngmgg+kr9hJ261TEvvnZMfgJmctBW6aZA6fyiGuN04i WOKELsraOwm/8ZMoJYojDd/ub99Q0OVIlON6LttXoabE/WZVaSsXE1BOJ36pBq7PO7guYz5kH3i zgW4DEFYHPM/4WLX+R/lzeVBVA07extj7Xl1dDHqOY2i1I7KJfGc6yg0lzfF1Y5RjTb6lJkdSKW QsYWtblZaXZv5va+RKCpZbO1r7XHi8X0tjfLZBWhshMm6n0bFJRN5wrUk+KKyrkBujtQ/dIjEy5 ITfH5FNWCEE2qAQ== X-Developer-Key: i=abel.vesa@linaro.org; a=openpgp; fpr=6AFF162D57F4223A8770EF5AF7BF214136F41FAE X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240329_115454_297513_D36F063C X-CRM114-Status: GOOD ( 17.69 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org Introduce the bus object in order to decouple the resources that are bus specific from the arbiter. This way the SPMI controller is registered with the generic framework at a bus level rather than arbiter. This is needed in order to prepare for multi bus support. Signed-off-by: Abel Vesa --- drivers/spmi/spmi-pmic-arb.c | 703 +++++++++++++++++++++++-------------------- 1 file changed, 372 insertions(+), 331 deletions(-) diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index 188252bfb95f..19ff8665f3d9 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -125,58 +126,72 @@ struct apid_data { u8 irq_ee; }; +struct spmi_pmic_arb; + /** - * struct spmi_pmic_arb - SPMI PMIC Arbiter object + * struct spmi_pmic_arb_bus - SPMI PMIC Arbiter Bus object * - * @rd_base: on v1 "core", on v2 "observer" register base off DT. - * @wr_base: on v1 "core", on v2 "chnls" register base off DT. + * @pmic_arb: the SPMI PMIC Arbiter the bus belongs to. + * @domain: irq domain object for PMIC IRQ domain * @intr: address of the SPMI interrupt control registers. * @cnfg: address of the PMIC Arbiter configuration registers. - * @lock: lock to synchronize accesses. - * @channel: execution environment channel to use for accesses. - * @irq: PMIC ARB interrupt. - * @ee: the current Execution Environment - * @bus_instance: on v7: 0 = primary SPMI bus, 1 = secondary SPMI bus - * @min_apid: minimum APID (used for bounding IRQ search) - * @max_apid: maximum APID + * @spmic: spmi controller registered for this bus * @base_apid: on v7: minimum APID associated with the particular SPMI * bus instance * @apid_count: on v5 and v7: number of APIDs associated with the * particular SPMI bus instance * @mapping_table: in-memory copy of PPID -> APID mapping table. - * @domain: irq domain object for PMIC IRQ domain - * @spmic: SPMI controller object - * @ver_ops: version dependent operations. + * @mapping_table_valid:bitmap containing valid-only periphs. * @ppid_to_apid: in-memory copy of PPID -> APID mapping table. * @last_apid: Highest value APID in use * @apid_data: Table of data for all APIDs + * @min_apid: minimum APID (used for bounding IRQ search) + * @max_apid: maximum APID + * @irq: PMIC ARB interrupt. + */ +struct spmi_pmic_arb_bus { + struct spmi_pmic_arb *pmic_arb; + struct irq_domain *domain; + void __iomem *intr; + void __iomem *cnfg; + struct spmi_controller *spmic; + u16 base_apid; + int apid_count; + u32 *mapping_table; + DECLARE_BITMAP(mapping_table_valid, PMIC_ARB_MAX_PERIPHS); + u16 *ppid_to_apid; + u16 last_apid; + struct apid_data *apid_data; + u16 min_apid; + u16 max_apid; + int irq; +}; + +/** + * struct spmi_pmic_arb - SPMI PMIC Arbiter object + * + * @rd_base: on v1 "core", on v2 "observer" register base off DT. + * @wr_base: on v1 "core", on v2 "chnls" register base off DT. + * @core: core register base for v2 and above only (see above) + * @core_size: core register base size + * @lock: lock to synchronize accesses. + * @channel: execution environment channel to use for accesses. + * @ee: the current Execution Environment + * @ver_ops: version dependent operations. * @max_periphs: Number of elements in apid_data[] + * @bus: per arbiter bus instance */ struct spmi_pmic_arb { void __iomem *rd_base; void __iomem *wr_base; - void __iomem *intr; - void __iomem *cnfg; void __iomem *core; resource_size_t core_size; raw_spinlock_t lock; u8 channel; - int irq; u8 ee; - u32 bus_instance; - u16 min_apid; - u16 max_apid; - u16 base_apid; - int apid_count; - u32 *mapping_table; - DECLARE_BITMAP(mapping_table_valid, PMIC_ARB_MAX_PERIPHS); - struct irq_domain *domain; - struct spmi_controller *spmic; const struct pmic_arb_ver_ops *ver_ops; - u16 *ppid_to_apid; - u16 last_apid; - struct apid_data *apid_data; int max_periphs; + struct spmi_pmic_arb_bus *bus; }; /** @@ -204,21 +219,21 @@ struct spmi_pmic_arb { struct pmic_arb_ver_ops { const char *ver_str; int (*get_core_resources)(struct platform_device *pdev, void __iomem *core); - int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index); - int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid); + int (*init_apid)(struct spmi_pmic_arb_bus *bus); + int (*ppid_to_apid)(struct spmi_pmic_arb_bus *bus, u16 ppid); /* spmi commands (read_cmd, write_cmd, cmd) functionality */ - int (*offset)(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr, - enum pmic_arb_channel ch_type); + int (*offset)(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr, + enum pmic_arb_channel ch_type); u32 (*fmt_cmd)(u8 opc, u8 sid, u16 addr, u8 bc); int (*non_data_cmd)(struct spmi_controller *ctrl, u8 opc, u8 sid); /* Interrupts controller functionality (offset of PIC registers) */ - void __iomem *(*owner_acc_status)(struct spmi_pmic_arb *pmic_arb, u8 m, + void __iomem *(*owner_acc_status)(struct spmi_pmic_arb_bus *bus, u8 m, u16 n); - void __iomem *(*acc_enable)(struct spmi_pmic_arb *pmic_arb, u16 n); - void __iomem *(*irq_status)(struct spmi_pmic_arb *pmic_arb, u16 n); - void __iomem *(*irq_clear)(struct spmi_pmic_arb *pmic_arb, u16 n); + void __iomem *(*acc_enable)(struct spmi_pmic_arb_bus *bus, u16 n); + void __iomem *(*irq_status)(struct spmi_pmic_arb_bus *bus, u16 n); + void __iomem *(*irq_clear)(struct spmi_pmic_arb_bus *bus, u16 n); u32 (*apid_map_offset)(u16 n); - void __iomem *(*apid_owner)(struct spmi_pmic_arb *pmic_arb, u16 n); + void __iomem *(*apid_owner)(struct spmi_pmic_arb_bus *bus, u16 n); }; static inline void pmic_arb_base_write(struct spmi_pmic_arb *pmic_arb, @@ -235,6 +250,7 @@ static inline void pmic_arb_set_rd_cmd(struct spmi_pmic_arb *pmic_arb, /** * pmic_arb_read_data: reads pmic-arb's register and copy 1..4 bytes to buf + * @pmic_arb: the SPMI PMIC arbiter * @bc: byte count -1. range: 0..3 * @reg: register's address * @buf: output parameter, length must be bc + 1 @@ -249,6 +265,7 @@ pmic_arb_read_data(struct spmi_pmic_arb *pmic_arb, u8 *buf, u32 reg, u8 bc) /** * pmic_arb_write_data: write 1..4 bytes from buf to pmic-arb's register + * @pmic_arb: the SPMI PMIC arbiter * @bc: byte-count -1. range: 0..3. * @reg: register's address. * @buf: buffer to write. length must be bc + 1. @@ -266,13 +283,14 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl, void __iomem *base, u8 sid, u16 addr, enum pmic_arb_channel ch_type) { - struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl); + struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl); + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; u32 status = 0; u32 timeout = PMIC_ARB_TIMEOUT_US; u32 offset; int rc; - rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr, ch_type); + rc = pmic_arb->ver_ops->offset(bus, sid, addr, ch_type); if (rc < 0) return rc; @@ -315,13 +333,14 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl, static int pmic_arb_non_data_cmd_v1(struct spmi_controller *ctrl, u8 opc, u8 sid) { - struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl); + struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl); + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; unsigned long flags; u32 cmd; int rc; u32 offset; - rc = pmic_arb->ver_ops->offset(pmic_arb, sid, 0, PMIC_ARB_CHANNEL_RW); + rc = pmic_arb->ver_ops->offset(bus, sid, 0, PMIC_ARB_CHANNEL_RW); if (rc < 0) return rc; @@ -357,20 +376,21 @@ static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid) return pmic_arb->ver_ops->non_data_cmd(ctrl, opc, sid); } -static int pmic_arb_fmt_read_cmd(struct spmi_pmic_arb *pmic_arb, u8 opc, u8 sid, +static int pmic_arb_fmt_read_cmd(struct spmi_pmic_arb_bus *bus, u8 opc, u8 sid, u16 addr, size_t len, u32 *cmd, u32 *offset) { + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; u8 bc = len - 1; int rc; - rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr, + rc = pmic_arb->ver_ops->offset(bus, sid, addr, PMIC_ARB_CHANNEL_OBS); if (rc < 0) return rc; *offset = rc; if (bc >= PMIC_ARB_MAX_TRANS_BYTES) { - dev_err(&pmic_arb->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested", + dev_err(&bus->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested", PMIC_ARB_MAX_TRANS_BYTES, len); return -EINVAL; } @@ -394,7 +414,8 @@ static int pmic_arb_read_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd, u32 offset, u8 sid, u16 addr, u8 *buf, size_t len) { - struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl); + struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl); + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; u8 bc = len - 1; int rc; @@ -416,12 +437,13 @@ static int pmic_arb_read_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd, static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, u16 addr, u8 *buf, size_t len) { - struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl); + struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl); + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; unsigned long flags; u32 cmd, offset; int rc; - rc = pmic_arb_fmt_read_cmd(pmic_arb, opc, sid, addr, len, &cmd, + rc = pmic_arb_fmt_read_cmd(bus, opc, sid, addr, len, &cmd, &offset); if (rc) return rc; @@ -433,21 +455,22 @@ static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, return rc; } -static int pmic_arb_fmt_write_cmd(struct spmi_pmic_arb *pmic_arb, u8 opc, +static int pmic_arb_fmt_write_cmd(struct spmi_pmic_arb_bus *bus, u8 opc, u8 sid, u16 addr, size_t len, u32 *cmd, u32 *offset) { + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; u8 bc = len - 1; int rc; - rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr, + rc = pmic_arb->ver_ops->offset(bus, sid, addr, PMIC_ARB_CHANNEL_RW); if (rc < 0) return rc; *offset = rc; if (bc >= PMIC_ARB_MAX_TRANS_BYTES) { - dev_err(&pmic_arb->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested", + dev_err(&bus->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested", PMIC_ARB_MAX_TRANS_BYTES, len); return -EINVAL; } @@ -473,7 +496,8 @@ static int pmic_arb_write_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd, u32 offset, u8 sid, u16 addr, const u8 *buf, size_t len) { - struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl); + struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl); + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; u8 bc = len - 1; /* Write data to FIFOs */ @@ -492,12 +516,13 @@ static int pmic_arb_write_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd, static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, u16 addr, const u8 *buf, size_t len) { - struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl); + struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl); + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; unsigned long flags; u32 cmd, offset; int rc; - rc = pmic_arb_fmt_write_cmd(pmic_arb, opc, sid, addr, len, &cmd, + rc = pmic_arb_fmt_write_cmd(bus, opc, sid, addr, len, &cmd, &offset); if (rc) return rc; @@ -513,18 +538,19 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, static int pmic_arb_masked_write(struct spmi_controller *ctrl, u8 sid, u16 addr, const u8 *buf, const u8 *mask, size_t len) { - struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl); + struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl); + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; u32 read_cmd, read_offset, write_cmd, write_offset; u8 temp[PMIC_ARB_MAX_TRANS_BYTES]; unsigned long flags; int rc, i; - rc = pmic_arb_fmt_read_cmd(pmic_arb, SPMI_CMD_EXT_READL, sid, addr, len, + rc = pmic_arb_fmt_read_cmd(bus, SPMI_CMD_EXT_READL, sid, addr, len, &read_cmd, &read_offset); if (rc) return rc; - rc = pmic_arb_fmt_write_cmd(pmic_arb, SPMI_CMD_EXT_WRITEL, sid, addr, + rc = pmic_arb_fmt_write_cmd(bus, SPMI_CMD_EXT_WRITEL, sid, addr, len, &write_cmd, &write_offset); if (rc) return rc; @@ -567,25 +593,25 @@ struct spmi_pmic_arb_qpnpint_type { static void qpnpint_spmi_write(struct irq_data *d, u8 reg, void *buf, size_t len) { - struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d); + struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d); u8 sid = hwirq_to_sid(d->hwirq); u8 per = hwirq_to_per(d->hwirq); - if (pmic_arb_write_cmd(pmic_arb->spmic, SPMI_CMD_EXT_WRITEL, sid, + if (pmic_arb_write_cmd(bus->spmic, SPMI_CMD_EXT_WRITEL, sid, (per << 8) + reg, buf, len)) - dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n", + dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x\n", d->irq); } static void qpnpint_spmi_read(struct irq_data *d, u8 reg, void *buf, size_t len) { - struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d); + struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d); u8 sid = hwirq_to_sid(d->hwirq); u8 per = hwirq_to_per(d->hwirq); - if (pmic_arb_read_cmd(pmic_arb->spmic, SPMI_CMD_EXT_READL, sid, + if (pmic_arb_read_cmd(bus->spmic, SPMI_CMD_EXT_READL, sid, (per << 8) + reg, buf, len)) - dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n", + dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x\n", d->irq); } @@ -593,47 +619,49 @@ static int qpnpint_spmi_masked_write(struct irq_data *d, u8 reg, const void *buf, const void *mask, size_t len) { - struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d); + struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d); u8 sid = hwirq_to_sid(d->hwirq); u8 per = hwirq_to_per(d->hwirq); int rc; - rc = pmic_arb_masked_write(pmic_arb->spmic, sid, (per << 8) + reg, buf, + rc = pmic_arb_masked_write(bus->spmic, sid, (per << 8) + reg, buf, mask, len); if (rc) - dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x rc=%d\n", + dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x rc=%d\n", d->irq, rc); return rc; } -static void cleanup_irq(struct spmi_pmic_arb *pmic_arb, u16 apid, int id) +static void cleanup_irq(struct spmi_pmic_arb_bus *bus, u16 apid, int id) { - u16 ppid = pmic_arb->apid_data[apid].ppid; + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; + u16 ppid = bus->apid_data[apid].ppid; u8 sid = ppid >> 8; u8 per = ppid & 0xFF; u8 irq_mask = BIT(id); - dev_err_ratelimited(&pmic_arb->spmic->dev, "%s apid=%d sid=0x%x per=0x%x irq=%d\n", - __func__, apid, sid, per, id); - writel_relaxed(irq_mask, pmic_arb->ver_ops->irq_clear(pmic_arb, apid)); + dev_err_ratelimited(&bus->spmic->dev, "%s apid=%d sid=0x%x per=0x%x irq=%d\n", + __func__, apid, sid, per, id); + writel_relaxed(irq_mask, pmic_arb->ver_ops->irq_clear(bus, apid)); } -static int periph_interrupt(struct spmi_pmic_arb *pmic_arb, u16 apid) +static int periph_interrupt(struct spmi_pmic_arb_bus *bus, u16 apid) { + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; unsigned int irq; u32 status, id; int handled = 0; - u8 sid = (pmic_arb->apid_data[apid].ppid >> 8) & 0xF; - u8 per = pmic_arb->apid_data[apid].ppid & 0xFF; + u8 sid = (bus->apid_data[apid].ppid >> 8) & 0xF; + u8 per = bus->apid_data[apid].ppid & 0xFF; - status = readl_relaxed(pmic_arb->ver_ops->irq_status(pmic_arb, apid)); + status = readl_relaxed(pmic_arb->ver_ops->irq_status(bus, apid)); while (status) { id = ffs(status) - 1; status &= ~BIT(id); - irq = irq_find_mapping(pmic_arb->domain, - spec_to_hwirq(sid, per, id, apid)); + irq = irq_find_mapping(bus->domain, + spec_to_hwirq(sid, per, id, apid)); if (irq == 0) { - cleanup_irq(pmic_arb, apid, id); + cleanup_irq(bus, apid, id); continue; } generic_handle_irq(irq); @@ -645,16 +673,17 @@ static int periph_interrupt(struct spmi_pmic_arb *pmic_arb, u16 apid) static void pmic_arb_chained_irq(struct irq_desc *desc) { - struct spmi_pmic_arb *pmic_arb = irq_desc_get_handler_data(desc); + struct spmi_pmic_arb_bus *bus = irq_desc_get_handler_data(desc); + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops; struct irq_chip *chip = irq_desc_get_chip(desc); - int first = pmic_arb->min_apid; - int last = pmic_arb->max_apid; + int first = bus->min_apid; + int last = bus->max_apid; /* * acc_offset will be non-zero for the secondary SPMI bus instance on * v7 controllers. */ - int acc_offset = pmic_arb->base_apid >> 5; + int acc_offset = bus->base_apid >> 5; u8 ee = pmic_arb->ee; u32 status, enable, handled = 0; int i, id, apid; @@ -665,7 +694,7 @@ static void pmic_arb_chained_irq(struct irq_desc *desc) chained_irq_enter(chip, desc); for (i = first >> 5; i <= last >> 5; ++i) { - status = readl_relaxed(ver_ops->owner_acc_status(pmic_arb, ee, i - acc_offset)); + status = readl_relaxed(ver_ops->owner_acc_status(bus, ee, i - acc_offset)); if (status) acc_valid = true; @@ -679,9 +708,9 @@ static void pmic_arb_chained_irq(struct irq_desc *desc) continue; } enable = readl_relaxed( - ver_ops->acc_enable(pmic_arb, apid)); + ver_ops->acc_enable(bus, apid)); if (enable & SPMI_PIC_ACC_ENABLE_BIT) - if (periph_interrupt(pmic_arb, apid) != 0) + if (periph_interrupt(bus, apid) != 0) handled++; } } @@ -690,19 +719,19 @@ static void pmic_arb_chained_irq(struct irq_desc *desc) if (!acc_valid) { for (i = first; i <= last; i++) { /* skip if APPS is not irq owner */ - if (pmic_arb->apid_data[i].irq_ee != pmic_arb->ee) + if (bus->apid_data[i].irq_ee != pmic_arb->ee) continue; irq_status = readl_relaxed( - ver_ops->irq_status(pmic_arb, i)); + ver_ops->irq_status(bus, i)); if (irq_status) { enable = readl_relaxed( - ver_ops->acc_enable(pmic_arb, i)); + ver_ops->acc_enable(bus, i)); if (enable & SPMI_PIC_ACC_ENABLE_BIT) { - dev_dbg(&pmic_arb->spmic->dev, + dev_dbg(&bus->spmic->dev, "Dispatching IRQ for apid=%d status=%x\n", i, irq_status); - if (periph_interrupt(pmic_arb, i) != 0) + if (periph_interrupt(bus, i) != 0) handled++; } } @@ -717,12 +746,13 @@ static void pmic_arb_chained_irq(struct irq_desc *desc) static void qpnpint_irq_ack(struct irq_data *d) { - struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d); + struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d); + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; u8 irq = hwirq_to_irq(d->hwirq); u16 apid = hwirq_to_apid(d->hwirq); u8 data; - writel_relaxed(BIT(irq), pmic_arb->ver_ops->irq_clear(pmic_arb, apid)); + writel_relaxed(BIT(irq), pmic_arb->ver_ops->irq_clear(bus, apid)); data = BIT(irq); qpnpint_spmi_write(d, QPNPINT_REG_LATCHED_CLR, &data, 1); @@ -738,14 +768,15 @@ static void qpnpint_irq_mask(struct irq_data *d) static void qpnpint_irq_unmask(struct irq_data *d) { - struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d); + struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d); + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops; u8 irq = hwirq_to_irq(d->hwirq); u16 apid = hwirq_to_apid(d->hwirq); u8 buf[2]; writel_relaxed(SPMI_PIC_ACC_ENABLE_BIT, - ver_ops->acc_enable(pmic_arb, apid)); + ver_ops->acc_enable(bus, apid)); qpnpint_spmi_read(d, QPNPINT_REG_EN_SET, &buf[0], 1); if (!(buf[0] & BIT(irq))) { @@ -802,9 +833,9 @@ static int qpnpint_irq_set_type(struct irq_data *d, unsigned int flow_type) static int qpnpint_irq_set_wake(struct irq_data *d, unsigned int on) { - struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d); + struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d); - return irq_set_irq_wake(pmic_arb->irq, on); + return irq_set_irq_wake(bus->irq, on); } static int qpnpint_get_irqchip_state(struct irq_data *d, @@ -826,17 +857,18 @@ static int qpnpint_get_irqchip_state(struct irq_data *d, static int qpnpint_irq_domain_activate(struct irq_domain *domain, struct irq_data *d, bool reserve) { - struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d); + struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d); + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; u16 periph = hwirq_to_per(d->hwirq); u16 apid = hwirq_to_apid(d->hwirq); u16 sid = hwirq_to_sid(d->hwirq); u16 irq = hwirq_to_irq(d->hwirq); u8 buf; - if (pmic_arb->apid_data[apid].irq_ee != pmic_arb->ee) { - dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner=%u\n", + if (bus->apid_data[apid].irq_ee != pmic_arb->ee) { + dev_err(&bus->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner=%u\n", sid, periph, irq, pmic_arb->ee, - pmic_arb->apid_data[apid].irq_ee); + bus->apid_data[apid].irq_ee); return -ENODEV; } @@ -863,15 +895,16 @@ static int qpnpint_irq_domain_translate(struct irq_domain *d, unsigned long *out_hwirq, unsigned int *out_type) { - struct spmi_pmic_arb *pmic_arb = d->host_data; + struct spmi_pmic_arb_bus *bus = d->host_data; + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; u32 *intspec = fwspec->param; u16 apid, ppid; int rc; - dev_dbg(&pmic_arb->spmic->dev, "intspec[0] 0x%1x intspec[1] 0x%02x intspec[2] 0x%02x\n", + dev_dbg(&bus->spmic->dev, "intspec[0] 0x%1x intspec[1] 0x%02x intspec[2] 0x%02x\n", intspec[0], intspec[1], intspec[2]); - if (irq_domain_get_of_node(d) != pmic_arb->spmic->dev.of_node) + if (irq_domain_get_of_node(d) != bus->spmic->dev.of_node) return -EINVAL; if (fwspec->param_count != 4) return -EINVAL; @@ -879,37 +912,37 @@ static int qpnpint_irq_domain_translate(struct irq_domain *d, return -EINVAL; ppid = intspec[0] << 8 | intspec[1]; - rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid); + rc = pmic_arb->ver_ops->ppid_to_apid(bus, ppid); if (rc < 0) { - dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u rc = %d\n", - intspec[0], intspec[1], intspec[2], rc); + dev_err(&bus->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u rc = %d\n", + intspec[0], intspec[1], intspec[2], rc); return rc; } apid = rc; /* Keep track of {max,min}_apid for bounding search during interrupt */ - if (apid > pmic_arb->max_apid) - pmic_arb->max_apid = apid; - if (apid < pmic_arb->min_apid) - pmic_arb->min_apid = apid; + if (apid > bus->max_apid) + bus->max_apid = apid; + if (apid < bus->min_apid) + bus->min_apid = apid; *out_hwirq = spec_to_hwirq(intspec[0], intspec[1], intspec[2], apid); *out_type = intspec[3] & IRQ_TYPE_SENSE_MASK; - dev_dbg(&pmic_arb->spmic->dev, "out_hwirq = %lu\n", *out_hwirq); + dev_dbg(&bus->spmic->dev, "out_hwirq = %lu\n", *out_hwirq); return 0; } static struct lock_class_key qpnpint_irq_lock_class, qpnpint_irq_request_class; -static void qpnpint_irq_domain_map(struct spmi_pmic_arb *pmic_arb, +static void qpnpint_irq_domain_map(struct spmi_pmic_arb_bus *bus, struct irq_domain *domain, unsigned int virq, irq_hw_number_t hwirq, unsigned int type) { irq_flow_handler_t handler; - dev_dbg(&pmic_arb->spmic->dev, "virq = %u, hwirq = %lu, type = %u\n", + dev_dbg(&bus->spmic->dev, "virq = %u, hwirq = %lu, type = %u\n", virq, hwirq, type); if (type & IRQ_TYPE_EDGE_BOTH) @@ -920,7 +953,7 @@ static void qpnpint_irq_domain_map(struct spmi_pmic_arb *pmic_arb, irq_set_lockdep_class(virq, &qpnpint_irq_lock_class, &qpnpint_irq_request_class); - irq_domain_set_info(domain, virq, hwirq, &pmic_arb_irqchip, pmic_arb, + irq_domain_set_info(domain, virq, hwirq, &pmic_arb_irqchip, bus, handler, NULL, NULL); } @@ -928,7 +961,7 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs, void *data) { - struct spmi_pmic_arb *pmic_arb = domain->host_data; + struct spmi_pmic_arb_bus *bus = domain->host_data; struct irq_fwspec *fwspec = data; irq_hw_number_t hwirq; unsigned int type; @@ -939,20 +972,22 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain, return ret; for (i = 0; i < nr_irqs; i++) - qpnpint_irq_domain_map(pmic_arb, domain, virq + i, hwirq + i, + qpnpint_irq_domain_map(bus, domain, virq + i, hwirq + i, type); return 0; } -static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb) +static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb_bus *bus) { + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; + /* * Initialize max_apid/min_apid to the opposite bounds, during * the irq domain translation, we are sure to update these */ - pmic_arb->max_apid = 0; - pmic_arb->min_apid = pmic_arb->max_periphs - 1; + bus->max_apid = 0; + bus->min_apid = pmic_arb->max_periphs - 1; return 0; } @@ -970,43 +1005,38 @@ static int pmic_arb_get_core_resources_v1(struct platform_device *pdev, return 0; } -static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index) +static int pmic_arb_init_apid_v1(struct spmi_pmic_arb_bus *bus) { + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; u32 *mapping_table; - if (index) { - dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n", - index); - return -EINVAL; - } - - mapping_table = devm_kcalloc(&pmic_arb->spmic->dev, pmic_arb->max_periphs, + mapping_table = devm_kcalloc(&bus->spmic->dev, pmic_arb->max_periphs, sizeof(*mapping_table), GFP_KERNEL); if (!mapping_table) return -ENOMEM; - pmic_arb->mapping_table = mapping_table; + bus->mapping_table = mapping_table; - return pmic_arb_init_apid_min_max(pmic_arb); + return pmic_arb_init_apid_min_max(bus); } -static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid) +static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb_bus *bus, u16 ppid) { - u32 *mapping_table = pmic_arb->mapping_table; + u32 *mapping_table = bus->mapping_table; int index = 0, i; u16 apid_valid; u16 apid; u32 data; - apid_valid = pmic_arb->ppid_to_apid[ppid]; + apid_valid = bus->ppid_to_apid[ppid]; if (apid_valid & PMIC_ARB_APID_VALID) { apid = apid_valid & ~PMIC_ARB_APID_VALID; return apid; } for (i = 0; i < SPMI_MAPPING_TABLE_TREE_DEPTH; ++i) { - if (!test_and_set_bit(index, pmic_arb->mapping_table_valid)) - mapping_table[index] = readl_relaxed(pmic_arb->cnfg + + if (!test_and_set_bit(index, bus->mapping_table_valid)) + mapping_table[index] = readl_relaxed(bus->cnfg + SPMI_MAPPING_TABLE_REG(index)); data = mapping_table[index]; @@ -1016,9 +1046,9 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid) index = SPMI_MAPPING_BIT_IS_1_RESULT(data); } else { apid = SPMI_MAPPING_BIT_IS_1_RESULT(data); - pmic_arb->ppid_to_apid[ppid] + bus->ppid_to_apid[ppid] = apid | PMIC_ARB_APID_VALID; - pmic_arb->apid_data[apid].ppid = ppid; + bus->apid_data[apid].ppid = ppid; return apid; } } else { @@ -1026,9 +1056,9 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid) index = SPMI_MAPPING_BIT_IS_0_RESULT(data); } else { apid = SPMI_MAPPING_BIT_IS_0_RESULT(data); - pmic_arb->ppid_to_apid[ppid] + bus->ppid_to_apid[ppid] = apid | PMIC_ARB_APID_VALID; - pmic_arb->apid_data[apid].ppid = ppid; + bus->apid_data[apid].ppid = ppid; return apid; } } @@ -1038,24 +1068,26 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid) } /* v1 offset per ee */ -static int pmic_arb_offset_v1(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr, - enum pmic_arb_channel ch_type) +static int pmic_arb_offset_v1(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr, + enum pmic_arb_channel ch_type) { + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; return 0x800 + 0x80 * pmic_arb->channel; } -static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid) +static u16 pmic_arb_find_apid(struct spmi_pmic_arb_bus *bus, u16 ppid) { - struct apid_data *apidd = &pmic_arb->apid_data[pmic_arb->last_apid]; + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; + struct apid_data *apidd = &bus->apid_data[bus->last_apid]; u32 regval, offset; u16 id, apid; - for (apid = pmic_arb->last_apid; ; apid++, apidd++) { + for (apid = bus->last_apid; ; apid++, apidd++) { offset = pmic_arb->ver_ops->apid_map_offset(apid); if (offset >= pmic_arb->core_size) break; - regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(pmic_arb, + regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(bus, apid)); apidd->irq_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval); apidd->write_ee = apidd->irq_ee; @@ -1065,14 +1097,14 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid) continue; id = (regval >> 8) & PMIC_ARB_PPID_MASK; - pmic_arb->ppid_to_apid[id] = apid | PMIC_ARB_APID_VALID; + bus->ppid_to_apid[id] = apid | PMIC_ARB_APID_VALID; apidd->ppid = id; if (id == ppid) { apid |= PMIC_ARB_APID_VALID; break; } } - pmic_arb->last_apid = apid & ~PMIC_ARB_APID_VALID; + bus->last_apid = apid & ~PMIC_ARB_APID_VALID; return apid; } @@ -1104,21 +1136,22 @@ static int pmic_arb_get_core_resources_v2(struct platform_device *pdev, return pmic_arb_get_obsrvr_chnls_v2(pdev); } -static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb *pmic_arb, u16 ppid) +static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb_bus *bus, u16 ppid) { u16 apid_valid; - apid_valid = pmic_arb->ppid_to_apid[ppid]; + apid_valid = bus->ppid_to_apid[ppid]; if (!(apid_valid & PMIC_ARB_APID_VALID)) - apid_valid = pmic_arb_find_apid(pmic_arb, ppid); + apid_valid = pmic_arb_find_apid(bus, ppid); if (!(apid_valid & PMIC_ARB_APID_VALID)) return -ENODEV; return apid_valid & ~PMIC_ARB_APID_VALID; } -static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb) +static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb_bus *bus) { + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; struct apid_data *apidd; struct apid_data *prev_apidd; u16 i, apid, ppid, apid_max; @@ -1140,9 +1173,9 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb) * where N = number of APIDs supported by the primary bus and * M = number of APIDs supported by the secondary bus */ - apidd = &pmic_arb->apid_data[pmic_arb->base_apid]; - apid_max = pmic_arb->base_apid + pmic_arb->apid_count; - for (i = pmic_arb->base_apid; i < apid_max; i++, apidd++) { + apidd = &bus->apid_data[bus->base_apid]; + apid_max = bus->base_apid + bus->apid_count; + for (i = bus->base_apid; i < apid_max; i++, apidd++) { offset = pmic_arb->ver_ops->apid_map_offset(i); if (offset >= pmic_arb->core_size) break; @@ -1153,19 +1186,18 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb) ppid = (regval >> 8) & PMIC_ARB_PPID_MASK; is_irq_ee = PMIC_ARB_CHAN_IS_IRQ_OWNER(regval); - regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(pmic_arb, - i)); + regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(bus, i)); apidd->write_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval); apidd->irq_ee = is_irq_ee ? apidd->write_ee : INVALID_EE; - valid = pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID; - apid = pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID; - prev_apidd = &pmic_arb->apid_data[apid]; + valid = bus->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID; + apid = bus->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID; + prev_apidd = &bus->apid_data[apid]; if (!valid || apidd->write_ee == pmic_arb->ee) { /* First PPID mapping or one for this EE */ - pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID; + bus->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID; } else if (valid && is_irq_ee && prev_apidd->write_ee == pmic_arb->ee) { /* @@ -1176,42 +1208,43 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb) } apidd->ppid = ppid; - pmic_arb->last_apid = i; + bus->last_apid = i; } /* Dump the mapping table for debug purposes. */ - dev_dbg(&pmic_arb->spmic->dev, "PPID APID Write-EE IRQ-EE\n"); + dev_dbg(&bus->spmic->dev, "PPID APID Write-EE IRQ-EE\n"); for (ppid = 0; ppid < PMIC_ARB_MAX_PPID; ppid++) { - apid = pmic_arb->ppid_to_apid[ppid]; + apid = bus->ppid_to_apid[ppid]; if (apid & PMIC_ARB_APID_VALID) { apid &= ~PMIC_ARB_APID_VALID; - apidd = &pmic_arb->apid_data[apid]; - dev_dbg(&pmic_arb->spmic->dev, "%#03X %3u %2u %2u\n", - ppid, apid, apidd->write_ee, apidd->irq_ee); + apidd = &bus->apid_data[apid]; + dev_dbg(&bus->spmic->dev, "%#03X %3u %2u %2u\n", + ppid, apid, apidd->write_ee, apidd->irq_ee); } } return 0; } -static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb *pmic_arb, u16 ppid) +static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb_bus *bus, u16 ppid) { - if (!(pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID)) + if (!(bus->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID)) return -ENODEV; - return pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID; + return bus->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID; } /* v2 offset per ppid and per ee */ -static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr, - enum pmic_arb_channel ch_type) +static int pmic_arb_offset_v2(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr, + enum pmic_arb_channel ch_type) { + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; u16 apid; u16 ppid; int rc; ppid = sid << 8 | ((addr >> 8) & 0xFF); - rc = pmic_arb_ppid_to_apid_v2(pmic_arb, ppid); + rc = pmic_arb_ppid_to_apid_v2(bus, ppid); if (rc < 0) return rc; @@ -1219,33 +1252,28 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr, return 0x1000 * pmic_arb->ee + 0x8000 * apid; } -static int pmic_arb_init_apid_v5(struct spmi_pmic_arb *pmic_arb, int index) +static int pmic_arb_init_apid_v5(struct spmi_pmic_arb_bus *bus) { + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; int ret; - if (index) { - dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n", - index); - return -EINVAL; - } - - pmic_arb->base_apid = 0; - pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) & + bus->base_apid = 0; + bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) & PMIC_ARB_FEATURES_PERIPH_MASK; - if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) { - dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n", - pmic_arb->base_apid + pmic_arb->apid_count); + if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) { + dev_err(&bus->spmic->dev, "Unsupported APID count %d detected\n", + bus->base_apid + bus->apid_count); return -EINVAL; } - ret = pmic_arb_init_apid_min_max(pmic_arb); + ret = pmic_arb_init_apid_min_max(bus); if (ret) return ret; - ret = pmic_arb_read_apid_map_v5(pmic_arb); + ret = pmic_arb_read_apid_map_v5(bus); if (ret) { - dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n", + dev_err(&bus->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n", ret); return ret; } @@ -1257,15 +1285,16 @@ static int pmic_arb_init_apid_v5(struct spmi_pmic_arb *pmic_arb, int index) * v5 offset per ee and per apid for observer channels and per apid for * read/write channels. */ -static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr, - enum pmic_arb_channel ch_type) +static int pmic_arb_offset_v5(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr, + enum pmic_arb_channel ch_type) { + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; u16 apid; int rc; u32 offset = 0; u16 ppid = (sid << 8) | (addr >> 8); - rc = pmic_arb_ppid_to_apid_v5(pmic_arb, ppid); + rc = pmic_arb_ppid_to_apid_v5(bus, ppid); if (rc < 0) return rc; @@ -1275,8 +1304,8 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr, offset = 0x10000 * pmic_arb->ee + 0x80 * apid; break; case PMIC_ARB_CHANNEL_RW: - if (pmic_arb->apid_data[apid].write_ee != pmic_arb->ee) { - dev_err(&pmic_arb->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n", + if (bus->apid_data[apid].write_ee != pmic_arb->ee) { + dev_err(&bus->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n", sid, addr); return -EPERM; } @@ -1299,62 +1328,20 @@ static int pmic_arb_get_core_resources_v7(struct platform_device *pdev, return pmic_arb_get_obsrvr_chnls_v2(pdev); } -/* - * Only v7 supports 2 buses. Each bus will get a different apid count, read - * from different registers. - */ -static int pmic_arb_init_apid_v7(struct spmi_pmic_arb *pmic_arb, int index) -{ - int ret; - - if (index == 0) { - pmic_arb->base_apid = 0; - pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) & - PMIC_ARB_FEATURES_PERIPH_MASK; - } else if (index == 1) { - pmic_arb->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) & - PMIC_ARB_FEATURES_PERIPH_MASK; - pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) & - PMIC_ARB_FEATURES_PERIPH_MASK; - } else { - dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n", - index); - return -EINVAL; - } - - if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) { - dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n", - pmic_arb->base_apid + pmic_arb->apid_count); - return -EINVAL; - } - - ret = pmic_arb_init_apid_min_max(pmic_arb); - if (ret) - return ret; - - ret = pmic_arb_read_apid_map_v5(pmic_arb); - if (ret) { - dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n", - ret); - return ret; - } - - return 0; -} - /* * v7 offset per ee and per apid for observer channels and per apid for * read/write channels. */ -static int pmic_arb_offset_v7(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr, - enum pmic_arb_channel ch_type) +static int pmic_arb_offset_v7(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr, + enum pmic_arb_channel ch_type) { + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; u16 apid; int rc; u32 offset = 0; u16 ppid = (sid << 8) | (addr >> 8); - rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid); + rc = pmic_arb->ver_ops->ppid_to_apid(bus, ppid); if (rc < 0) return rc; @@ -1364,8 +1351,8 @@ static int pmic_arb_offset_v7(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr, offset = 0x8000 * pmic_arb->ee + 0x20 * apid; break; case PMIC_ARB_CHANNEL_RW: - if (pmic_arb->apid_data[apid].write_ee != pmic_arb->ee) { - dev_err(&pmic_arb->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n", + if (bus->apid_data[apid].write_ee != pmic_arb->ee) { + dev_err(&bus->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n", sid, addr); return -EPERM; } @@ -1387,104 +1374,110 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc) } static void __iomem * -pmic_arb_owner_acc_status_v1(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n) +pmic_arb_owner_acc_status_v1(struct spmi_pmic_arb_bus *bus, u8 m, u16 n) { - return pmic_arb->intr + 0x20 * m + 0x4 * n; + return bus->intr + 0x20 * m + 0x4 * n; } static void __iomem * -pmic_arb_owner_acc_status_v2(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n) +pmic_arb_owner_acc_status_v2(struct spmi_pmic_arb_bus *bus, u8 m, u16 n) { - return pmic_arb->intr + 0x100000 + 0x1000 * m + 0x4 * n; + return bus->intr + 0x100000 + 0x1000 * m + 0x4 * n; } static void __iomem * -pmic_arb_owner_acc_status_v3(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n) +pmic_arb_owner_acc_status_v3(struct spmi_pmic_arb_bus *bus, u8 m, u16 n) { - return pmic_arb->intr + 0x200000 + 0x1000 * m + 0x4 * n; + return bus->intr + 0x200000 + 0x1000 * m + 0x4 * n; } static void __iomem * -pmic_arb_owner_acc_status_v5(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n) +pmic_arb_owner_acc_status_v5(struct spmi_pmic_arb_bus *bus, u8 m, u16 n) { - return pmic_arb->intr + 0x10000 * m + 0x4 * n; + return bus->intr + 0x10000 * m + 0x4 * n; } static void __iomem * -pmic_arb_owner_acc_status_v7(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n) +pmic_arb_owner_acc_status_v7(struct spmi_pmic_arb_bus *bus, u8 m, u16 n) { - return pmic_arb->intr + 0x1000 * m + 0x4 * n; + return bus->intr + 0x1000 * m + 0x4 * n; } static void __iomem * -pmic_arb_acc_enable_v1(struct spmi_pmic_arb *pmic_arb, u16 n) +pmic_arb_acc_enable_v1(struct spmi_pmic_arb_bus *bus, u16 n) { - return pmic_arb->intr + 0x200 + 0x4 * n; + return bus->intr + 0x200 + 0x4 * n; } static void __iomem * -pmic_arb_acc_enable_v2(struct spmi_pmic_arb *pmic_arb, u16 n) +pmic_arb_acc_enable_v2(struct spmi_pmic_arb_bus *bus, u16 n) { - return pmic_arb->intr + 0x1000 * n; + return bus->intr + 0x1000 * n; } static void __iomem * -pmic_arb_acc_enable_v5(struct spmi_pmic_arb *pmic_arb, u16 n) +pmic_arb_acc_enable_v5(struct spmi_pmic_arb_bus *bus, u16 n) { + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; return pmic_arb->wr_base + 0x100 + 0x10000 * n; } static void __iomem * -pmic_arb_acc_enable_v7(struct spmi_pmic_arb *pmic_arb, u16 n) +pmic_arb_acc_enable_v7(struct spmi_pmic_arb_bus *bus, u16 n) { + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; return pmic_arb->wr_base + 0x100 + 0x1000 * n; } static void __iomem * -pmic_arb_irq_status_v1(struct spmi_pmic_arb *pmic_arb, u16 n) +pmic_arb_irq_status_v1(struct spmi_pmic_arb_bus *bus, u16 n) { - return pmic_arb->intr + 0x600 + 0x4 * n; + return bus->intr + 0x600 + 0x4 * n; } static void __iomem * -pmic_arb_irq_status_v2(struct spmi_pmic_arb *pmic_arb, u16 n) +pmic_arb_irq_status_v2(struct spmi_pmic_arb_bus *bus, u16 n) { - return pmic_arb->intr + 0x4 + 0x1000 * n; + return bus->intr + 0x4 + 0x1000 * n; } static void __iomem * -pmic_arb_irq_status_v5(struct spmi_pmic_arb *pmic_arb, u16 n) +pmic_arb_irq_status_v5(struct spmi_pmic_arb_bus *bus, u16 n) { + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; return pmic_arb->wr_base + 0x104 + 0x10000 * n; } static void __iomem * -pmic_arb_irq_status_v7(struct spmi_pmic_arb *pmic_arb, u16 n) +pmic_arb_irq_status_v7(struct spmi_pmic_arb_bus *bus, u16 n) { + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; return pmic_arb->wr_base + 0x104 + 0x1000 * n; } static void __iomem * -pmic_arb_irq_clear_v1(struct spmi_pmic_arb *pmic_arb, u16 n) +pmic_arb_irq_clear_v1(struct spmi_pmic_arb_bus *bus, u16 n) { - return pmic_arb->intr + 0xA00 + 0x4 * n; + return bus->intr + 0xA00 + 0x4 * n; } static void __iomem * -pmic_arb_irq_clear_v2(struct spmi_pmic_arb *pmic_arb, u16 n) +pmic_arb_irq_clear_v2(struct spmi_pmic_arb_bus *bus, u16 n) { - return pmic_arb->intr + 0x8 + 0x1000 * n; + return bus->intr + 0x8 + 0x1000 * n; } static void __iomem * -pmic_arb_irq_clear_v5(struct spmi_pmic_arb *pmic_arb, u16 n) +pmic_arb_irq_clear_v5(struct spmi_pmic_arb_bus *bus, u16 n) { + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; return pmic_arb->wr_base + 0x108 + 0x10000 * n; } static void __iomem * -pmic_arb_irq_clear_v7(struct spmi_pmic_arb *pmic_arb, u16 n) +pmic_arb_irq_clear_v7(struct spmi_pmic_arb_bus *bus, u16 n) { + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; return pmic_arb->wr_base + 0x108 + 0x1000 * n; } @@ -1504,9 +1497,9 @@ static u32 pmic_arb_apid_map_offset_v7(u16 n) } static void __iomem * -pmic_arb_apid_owner_v2(struct spmi_pmic_arb *pmic_arb, u16 n) +pmic_arb_apid_owner_v2(struct spmi_pmic_arb_bus *bus, u16 n) { - return pmic_arb->cnfg + 0x700 + 0x4 * n; + return bus->cnfg + 0x700 + 0x4 * n; } /* @@ -1515,9 +1508,9 @@ pmic_arb_apid_owner_v2(struct spmi_pmic_arb *pmic_arb, u16 n) * 0. */ static void __iomem * -pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n) +pmic_arb_apid_owner_v7(struct spmi_pmic_arb_bus *bus, u16 n) { - return pmic_arb->cnfg + 0x4 * (n - pmic_arb->base_apid); + return bus->cnfg + 0x4 * (n - bus->base_apid); } static const struct pmic_arb_ver_ops pmic_arb_v1 = { @@ -1587,7 +1580,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = { static const struct pmic_arb_ver_ops pmic_arb_v7 = { .ver_str = "v7", .get_core_resources = pmic_arb_get_core_resources_v7, - .init_apid = pmic_arb_init_apid_v7, + .init_apid = pmic_arb_init_apid_v5, .ppid_to_apid = pmic_arb_ppid_to_apid_v5, .non_data_cmd = pmic_arb_non_data_cmd_v2, .offset = pmic_arb_offset_v7, @@ -1607,29 +1600,120 @@ static const struct irq_domain_ops pmic_arb_irq_domain_ops = { .translate = qpnpint_irq_domain_translate, }; +static int spmi_pmic_arb_bus_init(struct platform_device *pdev, + struct device_node *node, + struct spmi_pmic_arb *pmic_arb) +{ + struct spmi_pmic_arb_bus *bus; + struct device *dev = &pdev->dev; + struct spmi_controller *ctrl; + void __iomem *intr; + void __iomem *cnfg; + int index, ret; + u32 irq; + + ctrl = devm_spmi_controller_alloc(dev, sizeof(*bus)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + ctrl->cmd = pmic_arb_cmd; + ctrl->read_cmd = pmic_arb_read_cmd; + ctrl->write_cmd = pmic_arb_write_cmd; + + bus = spmi_controller_get_drvdata(ctrl); + + pmic_arb->bus = bus; + + bus->ppid_to_apid = devm_kcalloc(dev, PMIC_ARB_MAX_PPID, + sizeof(*bus->ppid_to_apid), + GFP_KERNEL); + if (!bus->ppid_to_apid) + return -ENOMEM; + + bus->apid_data = devm_kcalloc(dev, pmic_arb->max_periphs, + sizeof(*bus->apid_data), + GFP_KERNEL); + if (!bus->apid_data) + return -ENOMEM; + + index = of_property_match_string(node, "reg-names", "cnfg"); + if (index < 0) { + dev_err(dev, "cnfg reg region missing"); + return -EINVAL; + } + + cnfg = devm_of_iomap(dev, node, index, NULL); + if (IS_ERR(cnfg)) + return PTR_ERR(cnfg); + + index = of_property_match_string(node, "reg-names", "intr"); + if (index < 0) { + dev_err(dev, "intr reg region missing"); + return -EINVAL; + } + + intr = devm_of_iomap(dev, node, index, NULL); + if (IS_ERR(intr)) + return PTR_ERR(intr); + + irq = of_irq_get_byname(node, "periph_irq"); + if (irq < 0) + return irq; + + bus->pmic_arb = pmic_arb; + bus->intr = intr; + bus->cnfg = cnfg; + bus->irq = irq; + bus->spmic = ctrl; + + ret = pmic_arb->ver_ops->init_apid(bus); + if (ret) + return ret; + + dev_dbg(&pdev->dev, "adding irq domain\n"); + + bus->domain = irq_domain_add_tree(dev->of_node, + &pmic_arb_irq_domain_ops, bus); + if (!bus->domain) { + dev_err(&pdev->dev, "unable to create irq_domain\n"); + return -ENOMEM; + } + + irq_set_chained_handler_and_data(bus->irq, + pmic_arb_chained_irq, bus); + + ctrl->dev.of_node = node; + + ret = devm_spmi_controller_add(dev, ctrl); + if (ret) + return ret; + + return 0; +} + static int spmi_pmic_arb_probe(struct platform_device *pdev) { struct spmi_pmic_arb *pmic_arb; - struct spmi_controller *ctrl; + struct device *dev = &pdev->dev; struct resource *res; void __iomem *core; u32 channel, ee, hw_ver; int err; - ctrl = devm_spmi_controller_alloc(&pdev->dev, sizeof(*pmic_arb)); - if (IS_ERR(ctrl)) - return PTR_ERR(ctrl); - - pmic_arb = spmi_controller_get_drvdata(ctrl); - pmic_arb->spmic = ctrl; + pmic_arb = devm_kzalloc(dev, sizeof(*pmic_arb), GFP_KERNEL); + if (!pmic_arb) + return -ENOMEM; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core"); - core = devm_ioremap(&ctrl->dev, res->start, resource_size(res)); + core = devm_ioremap(dev, res->start, resource_size(res)); if (IS_ERR(core)) return PTR_ERR(core); pmic_arb->core_size = resource_size(res); + platform_set_drvdata(pdev, pmic_arb); + raw_spin_lock_init(&pmic_arb->lock); + hw_ver = readl_relaxed(core + PMIC_ARB_VERSION); if (hw_ver < PMIC_ARB_VERSION_V2_MIN) @@ -1643,30 +1727,12 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) else pmic_arb->ver_ops = &pmic_arb_v7; - dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n", - pmic_arb->ver_ops->ver_str, hw_ver); - err = pmic_arb->ver_ops->get_core_resources(pdev, core); if (err) return err; - err = pmic_arb->ver_ops->init_apid(pmic_arb, 0); - if (err) - return err; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr"); - pmic_arb->intr = devm_ioremap_resource(&ctrl->dev, res); - if (IS_ERR(pmic_arb->intr)) - return PTR_ERR(pmic_arb->intr); - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cnfg"); - pmic_arb->cnfg = devm_ioremap_resource(&ctrl->dev, res); - if (IS_ERR(pmic_arb->cnfg)) - return PTR_ERR(pmic_arb->cnfg); - - pmic_arb->irq = platform_get_irq_byname(pdev, "periph_irq"); - if (pmic_arb->irq < 0) - return pmic_arb->irq; + dev_info(dev, "PMIC arbiter version %s (0x%x)\n", + pmic_arb->ver_ops->ver_str, hw_ver); err = of_property_read_u32(pdev->dev.of_node, "qcom,channel", &channel); if (err) { @@ -1695,42 +1761,17 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) pmic_arb->ee = ee; - platform_set_drvdata(pdev, ctrl); - raw_spin_lock_init(&pmic_arb->lock); - - ctrl->cmd = pmic_arb_cmd; - ctrl->read_cmd = pmic_arb_read_cmd; - ctrl->write_cmd = pmic_arb_write_cmd; - - dev_dbg(&pdev->dev, "adding irq domain\n"); - pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node, - &pmic_arb_irq_domain_ops, pmic_arb); - if (!pmic_arb->domain) { - dev_err(&pdev->dev, "unable to create irq_domain\n"); - return -ENOMEM; - } - - irq_set_chained_handler_and_data(pmic_arb->irq, pmic_arb_chained_irq, - pmic_arb); - err = spmi_controller_add(ctrl); - if (err) - goto err_domain_remove; - - return 0; - -err_domain_remove: - irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL); - irq_domain_remove(pmic_arb->domain); - return err; + return spmi_pmic_arb_bus_init(pdev, dev->of_node, pmic_arb); } static void spmi_pmic_arb_remove(struct platform_device *pdev) { - struct spmi_controller *ctrl = platform_get_drvdata(pdev); - struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl); - spmi_controller_remove(ctrl); - irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL); - irq_domain_remove(pmic_arb->domain); + struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev); + struct spmi_pmic_arb_bus *bus = pmic_arb->bus; + + irq_set_chained_handler_and_data(bus->irq, + NULL, NULL); + irq_domain_remove(bus->domain); } static const struct of_device_id spmi_pmic_arb_match_table[] = { From patchwork Fri Mar 29 18:54:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Abel Vesa X-Patchwork-Id: 13610941 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 1523FC6FD1F for ; Fri, 29 Mar 2024 18:55:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References :Message-Id:Content-Transfer-Encoding:Content-Type: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=gDWmNiwFaDyG4eVDcOJIipMcHBjPEMX/8w3VIoSj37Y=; b=RUS++KwkwzhWKKJjNt4W0AQ146 /X52KBR68i+Cp+5N0xwZc0HR/XgJjYPVt2cW9Q5VFge2iPJOEMISM3+4NNn0xn3xYXdX5clcrTClS +IC5djAaTUZm3mm7Y3Llz8fzjZReqL9LEUfOJAVZSlhEbGby9fbm/U+PZDBbV4ItsCFWWElapDU8C 2ppAdBwV+RTyS7qLQhU+2Z7Ig7hvphWhJv5SB3thbyBSNBATQRMxPUvqUGDJ1J4rWK0TlEGeDpKkH gWd09SeDfRWohKIq+wyIqLfv2HzGpWZzufHyFBKepHVoGTX+oXPL61AnRymYlHdveL43VzbtI4bhA Ph5MwYIg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rqHOA-00000001fV5-2vja; Fri, 29 Mar 2024 18:55:42 +0000 Received: from mail-ed1-x533.google.com ([2a00:1450:4864:20::533]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1rqHNP-00000001f26-1TEp for linux-mediatek@lists.infradead.org; Fri, 29 Mar 2024 18:54:58 +0000 Received: by mail-ed1-x533.google.com with SMTP id 4fb4d7f45d1cf-56829f41f81so3326342a12.2 for ; Fri, 29 Mar 2024 11:54:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1711738492; x=1712343292; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=gDWmNiwFaDyG4eVDcOJIipMcHBjPEMX/8w3VIoSj37Y=; b=MWpSIJg3R21DgeihH+3pPHcOlG90pUGt4w5TuVtVjbeNdnZTNVwyWwWWMFibvCI/XL X+FVcM3SW8IL3s31+5L1yccip1yME2uI2pFkwD9yygcftaSRSKwl+yNEZZkFL1S/n2js ghhVsD4eNsNjGM8HT7PaMuiUUkR9rRRp/eiCygwf7LZecO+qXrGo3e6VGj7h+FDRQQcj eSRbjaZu5pvlU+6aURgfUKKMX6qT/1wYvck8H8GCdzmikzCAqbtMB083vwEF3/opqf8Q PuRQoHlfB2MK/ZSW+XrabVQLNh8VIC8d+PgKGvXgz89blwenIqljJrlE4HAZ+EwwFWgq w67Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711738492; x=1712343292; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gDWmNiwFaDyG4eVDcOJIipMcHBjPEMX/8w3VIoSj37Y=; b=JpXl2BwID2C8X2MOm+TxcgEMlXjWEU5pBW0/gruO8ToGkR953Ce5Ndfy+9DCd0KHBU HzJ99G3O8cTxFmq1a9jZzysHn5ln6uGU2r9/IxwGAQB9xx6CsHhgTc5ptDIrnwsT/mTW LgL4mujtkOGkd2NsCfHGOMFggtjLlB/YH3I8WpO/qTYM2wbztNIZSrVP9PKpmS8KToM9 OdLphpZADQmHuFtRqW2jG3ypSUciWD0lmq5GUTU+oYOEQvoEUgPsV7aq0rt+1xSB2lDO KYkpcxd9/zSTmzDlmEYIBxcxn0uQk0yQyGUYRp+pbUtLWYSX8gCVIK2XcRTO1d7MNPSJ 0bbQ== X-Forwarded-Encrypted: i=1; AJvYcCWltS4qgIJmryxNv+Bpy8ErbgCcdhBeWT9kX1FpyM9FkZY9FVdQVx9iDrOI2061XnFVDG2xhRVoXB2TjcIJwDNOWxF6KW7M4mLewBR0OHEvTuDH X-Gm-Message-State: AOJu0YwG9ZPCFwnjO4qhfTkyMMsSlonoghRn5W5yIpEiWBTtywWg9n5e AMyxYPUcuu46ip/HuPd3hKT0nTgqL+PQhuSk4Mt592tu3dioxm7KealfijW9+9I= X-Google-Smtp-Source: AGHT+IEtKEI1LK9lS1mHVw1CNmNQ33IUOsSWQyQtYl0YqK2TB+8vPQKsER18RfjFqRKtZmrSueU3Tw== X-Received: by 2002:a17:907:7248:b0:a4e:4350:3b3a with SMTP id ds8-20020a170907724800b00a4e43503b3amr604914ejc.60.1711738492180; Fri, 29 Mar 2024 11:54:52 -0700 (PDT) Received: from [127.0.1.1] ([79.114.172.194]) by smtp.gmail.com with ESMTPSA id gl20-20020a170906e0d400b00a46c39e6a47sm2235618ejb.148.2024.03.29.11.54.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 Mar 2024 11:54:51 -0700 (PDT) From: Abel Vesa Date: Fri, 29 Mar 2024 20:54:23 +0200 Subject: [PATCH v7 6/6] spmi: pmic-arb: Add multi bus support MIME-Version: 1.0 Message-Id: <20240329-spmi-multi-master-support-v7-6-7b902824246c@linaro.org> References: <20240329-spmi-multi-master-support-v7-0-7b902824246c@linaro.org> In-Reply-To: <20240329-spmi-multi-master-support-v7-0-7b902824246c@linaro.org> To: Stephen Boyd , Matthias Brugger , Bjorn Andersson , Konrad Dybcio , Dmitry Baryshkov , Neil Armstrong , AngeloGioacchino Del Regno , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Srini Kandagatla , Johan Hovold , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-arm-msm@vger.kernel.org, linux-mediatek@lists.infradead.org, devicetree@vger.kernel.org, Abel Vesa X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=9932; i=abel.vesa@linaro.org; h=from:subject:message-id; bh=kiFNbFrr2cHRGI8Y32geRObZcge4BmsO3+tXioPlQw4=; b=owEBbQKS/ZANAwAKARtfRMkAlRVWAcsmYgBmBw5wmKqlBnGcmeFRd+VPQ2FIeVnh7xAj2hE5P 1xfqvfLhuaJAjMEAAEKAB0WIQRO8+4RTnqPKsqn0bgbX0TJAJUVVgUCZgcOcAAKCRAbX0TJAJUV VgttD/4xWJelpoSyHqTyDbdFlLRkyQUAcHCnevhPtmBJNrAdG8olNyVCTHD8Zgmkwi2hTO/INbP 6aVYK9UMhvBAjLxEizLYZJOJj8h841CPzHCyQUFnPwDpgtHLfTSSqViD2UR9k3kNvqOEg2fdTt4 dF5bm4JgWn8Q6IvvqbHFFSjNWf84xwABYNuZeFhyMZKJx/Q9mQXKs57U92Q4H/Yz141LHavtbgb AQIEm7n3CcsVFuEt27D1wam5E8BIbR4kr3njpm+mLKR3yjD2o5lHwA0fCmzdqxonx71xF1hYp8D T4tuqf76OrXHGIISJUFvo4zmoadjRJ0iVb1Lxfm2X8u3hYnMA9uJKRPoIv3CD9SG3hyayc6507A pDsIvgQ6mMv5BGZvxQGPZAF5BN3G5gZrUTRnEnCzDZLghtgj34FCinwS3dkjb4IztalXTeE4+F7 pruaIcNfhkHMXvRBU0v0UuvgckIu66dpmmo1t/eDqet98NkVyQrNQ2wfmDc+BL5ngPYRP85SeV0 ey9Cs1RL1t8ysKAk1fHGyG7g6tSU9ZfDP3ZKpi5z5tioJ8fUgoj0G0nSwKblO7ZLcCVZt8zXRir eSzYb+Di00H1+UlltQl6SGuSsNlefLZ9KMy/JvFPPfOq5p7qnJrA9F/uVtZs+MQhG4XeLnQLg4K IZ9bCoWuAgLrZjw== X-Developer-Key: i=abel.vesa@linaro.org; a=openpgp; fpr=6AFF162D57F4223A8770EF5AF7BF214136F41FAE X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240329_115455_754183_D85DE2D5 X-CRM114-Status: GOOD ( 24.52 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org Starting with HW version 7, there are actually two separate buses (with two separate sets of wires). So add support for the second bus. The first platform that needs this support for the second bus is the Qualcomm X1 Elite, so add the compatible for it as well. Signed-off-by: Abel Vesa --- drivers/spmi/spmi-pmic-arb.c | 138 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 120 insertions(+), 18 deletions(-) diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index 19ff8665f3d9..56f2b3190d82 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -95,6 +96,8 @@ enum pmic_arb_channel { PMIC_ARB_CHANNEL_OBS, }; +#define PMIC_ARB_MAX_BUSES 2 + /* Maximum number of support PMIC peripherals */ #define PMIC_ARB_MAX_PERIPHS 512 #define PMIC_ARB_MAX_PERIPHS_V7 1024 @@ -148,6 +151,7 @@ struct spmi_pmic_arb; * @min_apid: minimum APID (used for bounding IRQ search) * @max_apid: maximum APID * @irq: PMIC ARB interrupt. + * @id: unique ID of the bus */ struct spmi_pmic_arb_bus { struct spmi_pmic_arb *pmic_arb; @@ -165,6 +169,7 @@ struct spmi_pmic_arb_bus { u16 min_apid; u16 max_apid; int irq; + u8 id; }; /** @@ -179,7 +184,8 @@ struct spmi_pmic_arb_bus { * @ee: the current Execution Environment * @ver_ops: version dependent operations. * @max_periphs: Number of elements in apid_data[] - * @bus: per arbiter bus instance + * @buses: per arbiter buses instances + * @buses_available: number of buses registered */ struct spmi_pmic_arb { void __iomem *rd_base; @@ -191,7 +197,8 @@ struct spmi_pmic_arb { u8 ee; const struct pmic_arb_ver_ops *ver_ops; int max_periphs; - struct spmi_pmic_arb_bus *bus; + struct spmi_pmic_arb_bus *buses[PMIC_ARB_MAX_BUSES]; + int buses_available; }; /** @@ -219,7 +226,7 @@ struct spmi_pmic_arb { struct pmic_arb_ver_ops { const char *ver_str; int (*get_core_resources)(struct platform_device *pdev, void __iomem *core); - int (*init_apid)(struct spmi_pmic_arb_bus *bus); + int (*init_apid)(struct spmi_pmic_arb_bus *bus, int index); int (*ppid_to_apid)(struct spmi_pmic_arb_bus *bus, u16 ppid); /* spmi commands (read_cmd, write_cmd, cmd) functionality */ int (*offset)(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr, @@ -308,8 +315,8 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl, } if (status & PMIC_ARB_STATUS_FAILURE) { - dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x)\n", - __func__, sid, addr, status); + dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x) reg: 0x%x\n", + __func__, sid, addr, status, offset); WARN_ON(1); return -EIO; } @@ -325,8 +332,8 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl, udelay(1); } - dev_err(&ctrl->dev, "%s: %#x %#x: timeout, status %#x\n", - __func__, sid, addr, status); + dev_err(&ctrl->dev, "%s: %#x %#x %#x: timeout, status %#x\n", + __func__, bus->id, sid, addr, status); return -ETIMEDOUT; } @@ -1005,11 +1012,17 @@ static int pmic_arb_get_core_resources_v1(struct platform_device *pdev, return 0; } -static int pmic_arb_init_apid_v1(struct spmi_pmic_arb_bus *bus) +static int pmic_arb_init_apid_v1(struct spmi_pmic_arb_bus *bus, int index) { struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; u32 *mapping_table; + if (index) { + dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n", + index); + return -EINVAL; + } + mapping_table = devm_kcalloc(&bus->spmic->dev, pmic_arb->max_periphs, sizeof(*mapping_table), GFP_KERNEL); if (!mapping_table) @@ -1252,11 +1265,17 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr, return 0x1000 * pmic_arb->ee + 0x8000 * apid; } -static int pmic_arb_init_apid_v5(struct spmi_pmic_arb_bus *bus) +static int pmic_arb_init_apid_v5(struct spmi_pmic_arb_bus *bus, int index) { struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; int ret; + if (index) { + dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n", + index); + return -EINVAL; + } + bus->base_apid = 0; bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) & PMIC_ARB_FEATURES_PERIPH_MASK; @@ -1328,6 +1347,50 @@ static int pmic_arb_get_core_resources_v7(struct platform_device *pdev, return pmic_arb_get_obsrvr_chnls_v2(pdev); } +/* + * Only v7 supports 2 buses. Each bus will get a different apid count, read + * from different registers. + */ +static int pmic_arb_init_apid_v7(struct spmi_pmic_arb_bus *bus, int index) +{ + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; + int ret; + + if (index == 0) { + bus->base_apid = 0; + bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) & + PMIC_ARB_FEATURES_PERIPH_MASK; + } else if (index == 1) { + bus->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) & + PMIC_ARB_FEATURES_PERIPH_MASK; + bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) & + PMIC_ARB_FEATURES_PERIPH_MASK; + } else { + dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n", + bus->id); + return -EINVAL; + } + + if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) { + dev_err(&bus->spmic->dev, "Unsupported APID count %d detected\n", + bus->base_apid + bus->apid_count); + return -EINVAL; + } + + ret = pmic_arb_init_apid_min_max(bus); + if (ret) + return ret; + + ret = pmic_arb_read_apid_map_v5(bus); + if (ret) { + dev_err(&bus->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n", + ret); + return ret; + } + + return 0; +} + /* * v7 offset per ee and per apid for observer channels and per apid for * read/write channels. @@ -1580,7 +1643,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = { static const struct pmic_arb_ver_ops pmic_arb_v7 = { .ver_str = "v7", .get_core_resources = pmic_arb_get_core_resources_v7, - .init_apid = pmic_arb_init_apid_v5, + .init_apid = pmic_arb_init_apid_v7, .ppid_to_apid = pmic_arb_ppid_to_apid_v5, .non_data_cmd = pmic_arb_non_data_cmd_v2, .offset = pmic_arb_offset_v7, @@ -1604,6 +1667,7 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev, struct device_node *node, struct spmi_pmic_arb *pmic_arb) { + int bus_index = pmic_arb->buses_available; struct spmi_pmic_arb_bus *bus; struct device *dev = &pdev->dev; struct spmi_controller *ctrl; @@ -1622,7 +1686,7 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev, bus = spmi_controller_get_drvdata(ctrl); - pmic_arb->bus = bus; + pmic_arb->buses[bus_index] = bus; bus->ppid_to_apid = devm_kcalloc(dev, PMIC_ARB_MAX_PPID, sizeof(*bus->ppid_to_apid), @@ -1665,12 +1729,13 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev, bus->cnfg = cnfg; bus->irq = irq; bus->spmic = ctrl; + bus->id = bus_index; - ret = pmic_arb->ver_ops->init_apid(bus); + ret = pmic_arb->ver_ops->init_apid(bus, bus_index); if (ret) return ret; - dev_dbg(&pdev->dev, "adding irq domain\n"); + dev_dbg(&pdev->dev, "adding irq domain for bus %d\n", bus_index); bus->domain = irq_domain_add_tree(dev->of_node, &pmic_arb_irq_domain_ops, bus); @@ -1683,14 +1748,53 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev, pmic_arb_chained_irq, bus); ctrl->dev.of_node = node; + dev_set_name(&ctrl->dev, "spmi-%d", bus_index); ret = devm_spmi_controller_add(dev, ctrl); if (ret) return ret; + pmic_arb->buses_available++; + return 0; } +static int spmi_pmic_arb_register_buses(struct spmi_pmic_arb *pmic_arb, + struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + struct device_node *child; + int ret; + + /* legacy mode doesn't provide child node for the bus */ + if (of_device_is_compatible(node, "qcom,spmi-pmic-arb")) + return spmi_pmic_arb_bus_init(pdev, node, pmic_arb); + + for_each_available_child_of_node(node, child) { + if (of_node_name_eq(child, "spmi")) { + ret = spmi_pmic_arb_bus_init(pdev, child, pmic_arb); + if (ret) + return ret; + } + } + + return ret; +} + +static void spmi_pmic_arb_deregister_buses(struct spmi_pmic_arb *pmic_arb) +{ + int i; + + for (i = 0; i < PMIC_ARB_MAX_BUSES; i++) { + struct spmi_pmic_arb_bus *bus = pmic_arb->buses[i]; + + irq_set_chained_handler_and_data(bus->irq, + NULL, NULL); + irq_domain_remove(bus->domain); + } +} + static int spmi_pmic_arb_probe(struct platform_device *pdev) { struct spmi_pmic_arb *pmic_arb; @@ -1761,21 +1865,19 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) pmic_arb->ee = ee; - return spmi_pmic_arb_bus_init(pdev, dev->of_node, pmic_arb); + return spmi_pmic_arb_register_buses(pmic_arb, pdev); } static void spmi_pmic_arb_remove(struct platform_device *pdev) { struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev); - struct spmi_pmic_arb_bus *bus = pmic_arb->bus; - irq_set_chained_handler_and_data(bus->irq, - NULL, NULL); - irq_domain_remove(bus->domain); + spmi_pmic_arb_deregister_buses(pmic_arb); } static const struct of_device_id spmi_pmic_arb_match_table[] = { { .compatible = "qcom,spmi-pmic-arb", }, + { .compatible = "qcom,x1e80100-spmi-pmic-arb", }, {}, }; MODULE_DEVICE_TABLE(of, spmi_pmic_arb_match_table);