From patchwork Fri Oct 8 01:25:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 515538 Delivered-To: patch@linaro.org Received: by 2002:ac0:b5cc:0:0:0:0:0 with SMTP id x12csp1675274ime; Thu, 7 Oct 2021 18:25:50 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxvEgCr0ippde52LIWLKtpKDCDSGBQvXPokfX1Ei0h223OAZwZRSsVfCMOhf/6yiXeD5/i4 X-Received: by 2002:a17:90b:30cb:: with SMTP id hi11mr9091588pjb.51.1633656350635; Thu, 07 Oct 2021 18:25:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1633656350; cv=none; d=google.com; s=arc-20160816; b=FDXBHXc7100lOZeaeEalVd2mGykvcRRZRKGw22Uqa0uVfoZFy/CMhvozwNxjumxZuB b5SSaYXPVJSJTZuC3Uwah2GcMO8hMApYcdKhaWlNlgy6IVcS0QW5wt7Zg4aKKTLtQ+/N JX+ULEd+Gwypq09KTm2MibbofrpUy+Nlr0nZPhtXvckkkCLt0wSESJMhv45VdmiB/QvR +26YGw5G8utuu/edTo717D1qJtH2uCDKaH6HJXHdmj2CLRxbOs1RniF/CtbWU1NWQpSg W21i5iEwvrvBSK7kf25Wb+omaID/AFEBG5adTN0BZlB5iW2kWKIliV5nZcKwTfytfSAI W/TA== 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=a82goinfuhMQndAZ1eqxYJiqwbzakFYRTc0Nku7E5EU=; b=ZzcqL1iNKunsOvtjE9cJ8C/7BfHsdElPltwKw9e3DREzh97dSMCfR1mj78i9Mwn+RE FCcviX7lyrQNlRppcriM5/vRHPAza8BgdJof+VJimKlNX6OFKWZxA9kBDFQFyc6jYuzR uDxtC6L9KXqf/lVH2OQfo4ZBKdN4h4SsOG3hIwyB0ZP6YzzC1heMEJlfFxOY+sdHWx+r iCMYyzjMvOySnPAamA67i1INIdWmKqRtZopOGBegkBa+fBCTLblvhGEG1rp/4uzWay0K SckUkCbrBtFxvHmnp5mf+Y8PN3AbpOhiXbvfi1Th+UbIx/PzfMkgeuSxMziAHkmaMQJr CZAg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=xf3Cvbd1; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-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 h7si1158223pgq.411.2021.10.07.18.25.50; Thu, 07 Oct 2021 18:25:50 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-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=xf3Cvbd1; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-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 S236195AbhJHB1m (ORCPT + 7 others); Thu, 7 Oct 2021 21:27:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38870 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234381AbhJHB1d (ORCPT ); Thu, 7 Oct 2021 21:27:33 -0400 Received: from mail-lf1-x133.google.com (mail-lf1-x133.google.com [IPv6:2a00:1450:4864:20::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E79E4C061760 for ; Thu, 7 Oct 2021 18:25:38 -0700 (PDT) Received: by mail-lf1-x133.google.com with SMTP id y26so32780992lfa.11 for ; Thu, 07 Oct 2021 18:25:38 -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=a82goinfuhMQndAZ1eqxYJiqwbzakFYRTc0Nku7E5EU=; b=xf3Cvbd1uHZ2yjcHWjFi5H5ffM/4fm71QLN44vHftTHY6owA066uh/KOufJ4jpzKZV 8xWmQoACICqT3doiygVInJ9OlxuBzkQ4b1DOVHX/GbfnA8hcuMuvLlYlguXIzgzag3xo wD5fpTpbZkyxR5hZI6bCT7U6eW4S9pOwId+NMz4OOpzoGpnoAse89786ENh7BMQOSk8T fTwZm2Cl2N7HLi0g8JXuABYzO+OwMM0znyvpwsxqSxKI7rqqVzbS7FPTwkPqt7CUAdi6 MinbYdkGbVG419oBSxafB1lH8g056F/B6cOPKNjCxLs1wqbMWDKkPrKLQcYyzWSXw6WH iLFA== 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=a82goinfuhMQndAZ1eqxYJiqwbzakFYRTc0Nku7E5EU=; b=NGguN64jndZfJTKxMujM3CKEiKiYP8i+VdUFVyzmwC4pWmLfsRA6aVKq2EvnPGTYtt zmDJNl7P1sJN0uI/J+b6NKYNeH33VImsU9l7zhtZ0xoUyqXOciRBujumdVqOep9EaxOR ZNNrcWaqKKY/Eq7BgvMnf6w7ytKv6GmQKwd16/34yQgkSacq6j4Jkob8jvl9iznVokNn 4fcOeUo9hbWL6/1u9kN4f4Q2ay6AMYfC5K9cJ6JqeYPsqGB29f1xPmK4C/1lQWVCO4PV Gn1I2KRUtDNVPcfrcjDLHZ8b2Mtu125XRMOoVYHK5tvDiG7/0+uY5ODXDAA1WcMRiSKl 8PSQ== X-Gm-Message-State: AOAM530Bik/tEILT813fH1uVymGJAgaeHPLwD7u1We1qsBuvw/Ly55tT ijg6DSSKrOlX9KK/jsqCZEuFxg== X-Received: by 2002:a2e:390d:: with SMTP id g13mr394279lja.78.1633656337278; Thu, 07 Oct 2021 18:25:37 -0700 (PDT) Received: from umbar.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id s4sm112875ljp.115.2021.10.07.18.25.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Oct 2021 18:25:36 -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 v3 14/25] pinctrl: qcom: ssbi-mpp: add support for hierarchical IRQ chip Date: Fri, 8 Oct 2021 04:25:13 +0300 Message-Id: <20211008012524.481877-15-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211008012524.481877-1-dmitry.baryshkov@linaro.org> References: <20211008012524.481877-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org ssbi-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 ssbi-mpp code to correct this issue. Signed-off-by: Dmitry Baryshkov --- drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c | 111 ++++++++++++++++++++---- 1 file changed, 93 insertions(+), 18 deletions(-) -- 2.30.2 diff --git a/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c b/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c index a90cada1d657..842940594c4a 100644 --- a/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c +++ b/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c @@ -87,7 +87,6 @@ /** * struct pm8xxx_pin_data - dynamic configuration for a pin * @reg: address of the control register - * @irq: IRQ from the PMIC interrupt controller * @mode: operating mode for the pin (digital, analog or current sink) * @input: pin is input * @output: pin is output @@ -103,7 +102,6 @@ */ struct pm8xxx_pin_data { unsigned reg; - int irq; u8 mode; @@ -126,6 +124,7 @@ struct pm8xxx_mpp { struct regmap *regmap; struct pinctrl_dev *pctrl; struct gpio_chip chip; + struct irq_chip irq; struct pinctrl_desc desc; unsigned npins; @@ -148,6 +147,8 @@ static const struct pin_config_item pm8xxx_conf_items[] = { #endif #define PM8XXX_MAX_MPPS 12 +#define PM8XXX_MPP_PHYSICAL_OFFSET 1 + static const char * const pm8xxx_groups[PM8XXX_MAX_MPPS] = { "mpp1", "mpp2", "mpp3", "mpp4", "mpp5", "mpp6", "mpp7", "mpp8", "mpp9", "mpp10", "mpp11", "mpp12", @@ -492,12 +493,16 @@ static int pm8xxx_mpp_get(struct gpio_chip *chip, unsigned offset) struct pm8xxx_mpp *pctrl = gpiochip_get_data(chip); struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data; bool state; - int ret; + int ret, irq; if (!pin->input) return !!pin->output_value; - ret = irq_get_irqchip_state(pin->irq, IRQCHIP_STATE_LINE_LEVEL, &state); + irq = chip->to_irq(chip, offset); + if (irq < 0) + return irq; + + ret = irq_get_irqchip_state(irq, IRQCHIP_STATE_LINE_LEVEL, &state); if (!ret) ret = !!state; @@ -524,18 +529,10 @@ static int pm8xxx_mpp_of_xlate(struct gpio_chip *chip, if (flags) *flags = gpio_desc->args[1]; - return gpio_desc->args[0] - 1; + return gpio_desc->args[0] - PM8XXX_MPP_PHYSICAL_OFFSET; } -static int pm8xxx_mpp_to_irq(struct gpio_chip *chip, unsigned offset) -{ - struct pm8xxx_mpp *pctrl = gpiochip_get_data(chip); - struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data; - - return pin->irq; -} - #ifdef CONFIG_DEBUG_FS #include @@ -558,7 +555,7 @@ static void pm8xxx_mpp_dbg_show_one(struct seq_file *s, "abus3", }; - seq_printf(s, " mpp%-2d:", offset + 1); + seq_printf(s, " mpp%-2d:", offset + PM8XXX_MPP_PHYSICAL_OFFSET); switch (pin->mode) { case PM8XXX_MPP_DIGITAL: @@ -640,7 +637,6 @@ static const struct gpio_chip pm8xxx_mpp_template = { .get = pm8xxx_mpp_get, .set = pm8xxx_mpp_set, .of_xlate = pm8xxx_mpp_of_xlate, - .to_irq = pm8xxx_mpp_to_irq, .dbg_show = pm8xxx_mpp_dbg_show, .owner = THIS_MODULE, }; @@ -732,6 +728,55 @@ static int pm8xxx_pin_populate(struct pm8xxx_mpp *pctrl, return 0; } +static int pm8xxx_mpp_domain_translate(struct irq_domain *domain, + struct irq_fwspec *fwspec, + unsigned long *hwirq, + unsigned int *type) +{ + struct pm8xxx_mpp *pctrl = container_of(domain->host_data, + struct pm8xxx_mpp, chip); + + if (fwspec->param_count != 2 || + fwspec->param[0] < PM8XXX_MPP_PHYSICAL_OFFSET || + fwspec->param[0] > pctrl->chip.ngpio) + return -EINVAL; + + *hwirq = fwspec->param[0] - PM8XXX_MPP_PHYSICAL_OFFSET; + *type = fwspec->param[1]; + + return 0; +} + +static unsigned int pm8xxx_mpp_child_offset_to_irq(struct gpio_chip *chip, + unsigned int offset) +{ + return offset + PM8XXX_MPP_PHYSICAL_OFFSET; +} + +static int pm8821_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 + 24; + *parent_type = child_type; + + return 0; +} + +static int pm8xxx_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 + 0x80; + *parent_type = child_type; + + return 0; +} + static const struct of_device_id pm8xxx_mpp_of_match[] = { { .compatible = "qcom,pm8018-mpp", .data = (void *) 6 }, { .compatible = "qcom,pm8038-mpp", .data = (void *) 6 }, @@ -746,7 +791,10 @@ MODULE_DEVICE_TABLE(of, pm8xxx_mpp_of_match); static int pm8xxx_mpp_probe(struct platform_device *pdev) { struct pm8xxx_pin_data *pin_data; + struct irq_domain *parent_domain; + struct device_node *parent_node; struct pinctrl_pin_desc *pins; + struct gpio_irq_chip *girq; struct pm8xxx_mpp *pctrl; int ret; int i; @@ -783,9 +831,6 @@ static int pm8xxx_mpp_probe(struct platform_device *pdev) for (i = 0; i < pctrl->desc.npins; i++) { pin_data[i].reg = SSBI_REG_ADDR_MPP(i); - pin_data[i].irq = platform_get_irq(pdev, i); - if (pin_data[i].irq < 0) - return pin_data[i].irq; ret = pm8xxx_pin_populate(pctrl, &pin_data[i]); if (ret) @@ -816,6 +861,36 @@ static int pm8xxx_mpp_probe(struct platform_device *pdev) pctrl->chip.of_gpio_n_cells = 2; pctrl->chip.label = dev_name(pctrl->dev); pctrl->chip.ngpio = pctrl->npins; + + parent_node = of_irq_find_parent(pctrl->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; + + pctrl->irq.name = "ssbi-mpp"; + pctrl->irq.irq_mask_ack = irq_chip_mask_ack_parent; + pctrl->irq.irq_unmask = irq_chip_unmask_parent; + pctrl->irq.irq_set_type = irq_chip_set_type_parent; + pctrl->irq.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE; + + girq = &pctrl->chip.irq; + girq->chip = &pctrl->irq; + girq->default_type = IRQ_TYPE_NONE; + girq->handler = handle_level_irq; + girq->fwnode = of_node_to_fwnode(pctrl->dev->of_node); + girq->parent_domain = parent_domain; + if (of_device_is_compatible(pdev->dev.of_node, "qcom,pm8821-mpp")) + girq->child_to_parent_hwirq = pm8821_mpp_child_to_parent_hwirq; + else + girq->child_to_parent_hwirq = pm8xxx_mpp_child_to_parent_hwirq; + girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_twocell; + girq->child_offset_to_irq = pm8xxx_mpp_child_offset_to_irq; + girq->child_irq_domain_ops.translate = pm8xxx_mpp_domain_translate; + ret = gpiochip_add_data(&pctrl->chip, pctrl); if (ret) { dev_err(&pdev->dev, "failed register gpiochip\n");