From patchwork Tue Oct 5 14:43:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 515252 Delivered-To: patch@linaro.org Received: by 2002:ac0:890a:0:0:0:0:0 with SMTP id 10csp1986691imy; Tue, 5 Oct 2021 07:43:48 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyI7ZG8wS/OOJ3nbZCwP5O7PEqKXxgja81xlC5gb3jLAHsXLBixwZNf69FCPOUA1nbGmPiW X-Received: by 2002:a17:906:6a8c:: with SMTP id p12mr25019813ejr.486.1633445028476; Tue, 05 Oct 2021 07:43:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1633445028; cv=none; d=google.com; s=arc-20160816; b=JubP6FyeV56sKycHYN8Fj1sLhLaL4thAZXxturlynnhoPTw0jsFbO/pAdeJmSlyXhL CUior8T15Tv1ZHPcTnzNMYMeVadlND80MT7kQ8mMLQOJG98i0YGzXp4WI05pRqKvFy9d LsdD0kM2ZQGVnCzQdoSjxK+/35f2pqkdOACv+4X/SclV41zLjVLKy/iPpQ4Kabalac64 FLXKYFEqyl1I/Letgh1HOkBrozkY51yT6u3BMlJYK8y6Nlgk6LKGApwkH4QRvJfDevNW XllZFKbYmPUmT4c/AvWMhACGIabYC3wEUHbaxImZMZPrAutzX05Y+ggeMfr/yYd+Y/ss IBcA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=E2YJV+cRv0tFDhiSivfR6SvH37WdzUlDmvLwCor6dDY=; b=UaZHwyoKo2sZ0EZQcPbQRub58ytVxTlY3oCTL/1xk2KTt2EywsI3WvrREiMIY9QVks Og2T0kbLVLpteccQf7rrtXwA+hRcmMYF17Zx033xc2WaEt6QNRLzShHjydYaQvSNorEm pDwVNm/bEe4gqewUXgPVJ8lbDbqTPEGV0d2p+rLWUnMGehXd0Mfrffz2ZWaf0DooJRLq +Vvp9UlH1eNUq0avK4kAkuC0YdTSIwbhLuZmDeYfkaN2I4zYCvr7yCAcPqw7Jmvncg5V Tk+zfGMTFnEdwPMMy+Xgh1epnIzN3xFpa4U39SnS3Ar+pfcoWHrBSRLl6x89W+B0lFAs lzVw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=RNO75yws; spf=pass (google.com: domain of linux-gpio-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-gpio-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id s11si24811738edh.626.2021.10.05.07.43.48; Tue, 05 Oct 2021 07:43:48 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-gpio-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=RNO75yws; spf=pass (google.com: domain of linux-gpio-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-gpio-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235325AbhJEOpd (ORCPT + 3 others); Tue, 5 Oct 2021 10:45:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48776 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235289AbhJEOpc (ORCPT ); Tue, 5 Oct 2021 10:45:32 -0400 Received: from mail-lf1-x135.google.com (mail-lf1-x135.google.com [IPv6:2a00:1450:4864:20::135]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A78C5C061766 for ; Tue, 5 Oct 2021 07:43:41 -0700 (PDT) Received: by mail-lf1-x135.google.com with SMTP id u18so87525130lfd.12 for ; Tue, 05 Oct 2021 07:43:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=E2YJV+cRv0tFDhiSivfR6SvH37WdzUlDmvLwCor6dDY=; b=RNO75ywst6VusRTOSyrP3384uvp9Io+Kr0VZ6hSkOXSkwALBRjXIyk51iRKNeCFPA2 r9621ip4YjSvLjNE7Eq3ZINWyeiByJqNJliNuoaGSBwxvzU5cJfAA74DefpokBzIf6VV BGHplVtWfLYZ2bI7Ct+QQYi8bkcnnfDNoCzNOnWEvvCh/l8wTyB5gyMlaqQCYuqEWAzN 4ZRgFQzETdFf7l5dMYUjAkDE/qZ6cez+DBQf4x6GIbIFRIDQPrvxFwLXemgy3LDmxnUT 6CJutLLxL5/EIWJAcDNyJnTgJ8lsL/OweKuR99+Gow6YVWoKsAKqF9wzRM8Q3VRkoRyJ 6bTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=E2YJV+cRv0tFDhiSivfR6SvH37WdzUlDmvLwCor6dDY=; b=0nrGT0lTkwEbsw4lYXgB0SEyASL4OCg3YVAESFcJmqyXcYdewxkGpThq17KwxCkbZf CTsIUY3rTN/jh1/3gPCC4VsadH7P4liSQZriGPD2pV51lHhrYhHE2AiXN2itgUgcDRQP sVyAO194bNLlh3jXctSpFiyRAZj8y+CvSm8Burs1mm89c+41o/dbC5oZAwXs2mr13aFv xLaCkGnVyaT7ZDlm03MuywKwXOP2XXrllVvD96d5x2OfE54fZCPFMX0Ua8P1JvQ3Db6I IXKS6yL6F5NUjsp6GwHOirvULVc6osRYKHZq62bSnxeGE3LAl99N/8cEj28HdAO2kPQN hyUg== X-Gm-Message-State: AOAM531JeMAMJAzQQtBOIyAyj+2dNJ98vyYbSSy1v5W8nhc3H+t4yake JSeFI92ifbYrjY0MUSHsRWMJ5Q== X-Received: by 2002:a05:6512:128b:: with SMTP id u11mr4097553lfs.24.1633445020052; Tue, 05 Oct 2021 07:43:40 -0700 (PDT) Received: from umbar.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id t22sm1987173ljc.120.2021.10.05.07.43.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Oct 2021 07:43:39 -0700 (PDT) From: Dmitry Baryshkov To: Andy Gross , Bjorn Andersson , Linus Walleij , Rob Herring Cc: linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-msm@vger.kernel.org Subject: [PATCH v2 6/6] pinctrl: qcom: spmi-mpp: add support for hierarchical IRQ chip Date: Tue, 5 Oct 2021 17:43:29 +0300 Message-Id: <20211005144329.2405315-7-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211005144329.2405315-1-dmitry.baryshkov@linaro.org> References: <20211005144329.2405315-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org spmi-mpp did not have any irqchip support so consumers of this in device tree would need to call gpio[d]_to_irq() in order to get the proper IRQ on the underlying PMIC. IRQ chips in device tree should be usable from the start without the consumer having to make an additional call to get the proper IRQ on the parent. This patch adds hierarchical IRQ chip support to the spmi-mpp code to correct this issue. Signed-off-by: Dmitry Baryshkov --- drivers/pinctrl/qcom/pinctrl-spmi-mpp.c | 86 ++++++++++++++++++++----- 1 file changed, 69 insertions(+), 17 deletions(-) -- 2.30.2 diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c index a9f994863126..b80723928b7e 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c @@ -103,7 +103,6 @@ /** * struct pmic_mpp_pad - keep current MPP settings * @base: Address base in SPMI device. - * @irq: IRQ number which this MPP generate. * @is_enabled: Set to false when MPP should be put in high Z state. * @out_value: Cached pin output value. * @output_enabled: Set to true if MPP output logic is enabled. @@ -121,7 +120,6 @@ */ struct pmic_mpp_pad { u16 base; - int irq; bool is_enabled; bool out_value; bool output_enabled; @@ -143,6 +141,7 @@ struct pmic_mpp_state { struct regmap *map; struct pinctrl_dev *ctrl; struct gpio_chip chip; + struct irq_chip irq; }; static const struct pinconf_generic_params pmic_mpp_bindings[] = { @@ -622,16 +621,6 @@ static int pmic_mpp_of_xlate(struct gpio_chip *chip, return gpio_desc->args[0] - PMIC_MPP_PHYSICAL_OFFSET; } -static int pmic_mpp_to_irq(struct gpio_chip *chip, unsigned pin) -{ - struct pmic_mpp_state *state = gpiochip_get_data(chip); - struct pmic_mpp_pad *pad; - - pad = state->ctrl->desc->pins[pin].drv_data; - - return pad->irq; -} - static void pmic_mpp_dbg_show(struct seq_file *s, struct gpio_chip *chip) { struct pmic_mpp_state *state = gpiochip_get_data(chip); @@ -651,7 +640,6 @@ static const struct gpio_chip pmic_mpp_gpio_template = { .request = gpiochip_generic_request, .free = gpiochip_generic_free, .of_xlate = pmic_mpp_of_xlate, - .to_irq = pmic_mpp_to_irq, .dbg_show = pmic_mpp_dbg_show, }; @@ -796,13 +784,53 @@ static int pmic_mpp_populate(struct pmic_mpp_state *state, return 0; } +static int pmic_mpp_domain_translate(struct irq_domain *domain, + struct irq_fwspec *fwspec, + unsigned long *hwirq, + unsigned int *type) +{ + struct pmic_mpp_state *state = container_of(domain->host_data, + struct pmic_mpp_state, + chip); + + if (fwspec->param_count != 2 || + fwspec->param[0] < 1 || fwspec->param[0] > state->chip.ngpio) + return -EINVAL; + + *hwirq = fwspec->param[0] - PMIC_MPP_PHYSICAL_OFFSET; + *type = fwspec->param[1]; + + return 0; +} + +static unsigned int pmic_mpp_child_offset_to_irq(struct gpio_chip *chip, + unsigned int offset) +{ + return offset + PMIC_MPP_PHYSICAL_OFFSET; +} + +static int pmic_mpp_child_to_parent_hwirq(struct gpio_chip *chip, + unsigned int child_hwirq, + unsigned int child_type, + unsigned int *parent_hwirq, + unsigned int *parent_type) +{ + *parent_hwirq = child_hwirq + 0xc0; + *parent_type = child_type; + + return 0; +} + static int pmic_mpp_probe(struct platform_device *pdev) { + struct irq_domain *parent_domain; + struct device_node *parent_node; struct device *dev = &pdev->dev; struct pinctrl_pin_desc *pindesc; struct pinctrl_desc *pctrldesc; struct pmic_mpp_pad *pad, *pads; struct pmic_mpp_state *state; + struct gpio_irq_chip *girq; int ret, npins, i; u32 reg; @@ -857,10 +885,6 @@ static int pmic_mpp_probe(struct platform_device *pdev) pindesc->number = i; pindesc->name = pmic_mpp_groups[i]; - pad->irq = platform_get_irq(pdev, i); - if (pad->irq < 0) - return pad->irq; - pad->base = reg + i * PMIC_MPP_ADDRESS_RANGE; ret = pmic_mpp_populate(state, pad); @@ -880,6 +904,34 @@ static int pmic_mpp_probe(struct platform_device *pdev) if (IS_ERR(state->ctrl)) return PTR_ERR(state->ctrl); + parent_node = of_irq_find_parent(state->dev->of_node); + if (!parent_node) + return -ENXIO; + + parent_domain = irq_find_host(parent_node); + of_node_put(parent_node); + if (!parent_domain) + return -ENXIO; + + state->irq.name = "spmi-mpp", + state->irq.irq_ack = irq_chip_ack_parent, + state->irq.irq_mask = irq_chip_mask_parent, + state->irq.irq_unmask = irq_chip_unmask_parent, + state->irq.irq_set_type = irq_chip_set_type_parent, + state->irq.irq_set_wake = irq_chip_set_wake_parent, + state->irq.flags = IRQCHIP_MASK_ON_SUSPEND, + + girq = &state->chip.irq; + girq->chip = &state->irq; + girq->default_type = IRQ_TYPE_NONE; + girq->handler = handle_level_irq; + girq->fwnode = of_node_to_fwnode(state->dev->of_node); + girq->parent_domain = parent_domain; + girq->child_to_parent_hwirq = pmic_mpp_child_to_parent_hwirq; + girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_fourcell; + girq->child_offset_to_irq = pmic_mpp_child_offset_to_irq; + girq->child_irq_domain_ops.translate = pmic_mpp_domain_translate; + ret = gpiochip_add_data(&state->chip, state); if (ret) { dev_err(state->dev, "can't add gpio chip\n");