Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp4576801imu; Sat, 19 Jan 2019 12:49:03 -0800 (PST) X-Google-Smtp-Source: ALg8bN57UgOm0nIpd//AM2DhgDDxRYunnqJRoCUrMiNKSTV40VrwgAL6kJjNlujCIYZwlZTjRUxa X-Received: by 2002:a63:4f5e:: with SMTP id p30mr22619641pgl.71.1547930943292; Sat, 19 Jan 2019 12:49:03 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1547930943; cv=none; d=google.com; s=arc-20160816; b=bry0iiQyFhBPCuEn954PAqcdfvm56ypZ/qbk1kbCd854cBScBLkdpfsQBbRHxJMGqP iECn+odNLGK1d+la0YXT/P35XmmiQ8FsfUwok/OTlAt+kK9H0bwmbRFO1/hiCxW94u0C GeSm+kXDvYdRIA3/1m7ptzITgh+9pDGLT0xEVFmuSoxG73m3L99UtmaL2Y3bHq0jEwWy /s//SThUTQnn69FGRts3kiz3y3l5hSBHpO20qZoQ/NlAI41oaEeKGPWyIv5gFpLTPTYx CZ214iFIsPsGiRT54/lwKbO7SPOM3oHujSHsRaayo5bvXsMHYykIoDIaY4DfAT8AsRHw gqwg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=swd37E4eGnAfpUhTa/xeYNjQrrH5JO1Gq7DQUEPh+gU=; b=tUQt+1CLW8eH4N49KNG94tMMHWzF54Qx/IjhMs7Jt/vVhnUZglhKhizJFhPKo6Pk+1 PNMVvUJy1jXA5pxqDj4uQ0SJcp60Gv/qgjozisC8HvNydme4iNReTGCxu2asl2uXq49z pvLHRYYFRtk81u3cIrxgK2kug22H+NKBarAH/JQeHYzwL/t5Oi4lEHZ7bNf/RAAF3aT+ 9VVzOfHqkkbgLhele7HSvARTsGkiZ4D7QMxNI6C8x004b7e73wc1v6K3P37RwCmVOD0C ttmYiJrNHLkt4nnSCRhOnvD1v/5xJ3c3UQGDq7+6hVe3tCWptLKatajXEMObzwYc5MTf SfbA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail (test mode) header.i=@onstation.org header.s=default header.b=Gxqj50v0; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d12si8389596pln.340.2019.01.19.12.48.45; Sat, 19 Jan 2019 12:49:03 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail (test mode) header.i=@onstation.org header.s=default header.b=Gxqj50v0; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730140AbfASUoy (ORCPT + 99 others); Sat, 19 Jan 2019 15:44:54 -0500 Received: from onstation.org ([52.200.56.107]:35190 "EHLO onstation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729175AbfASUne (ORCPT ); Sat, 19 Jan 2019 15:43:34 -0500 Received: from localhost.localdomain (c-98-239-145-235.hsd1.wv.comcast.net [98.239.145.235]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: masneyb) by onstation.org (Postfix) with ESMTPSA id 47DAE76A; Sat, 19 Jan 2019 20:43:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=onstation.org; s=default; t=1547930612; bh=RuioL+4LP940FlBCUos7aPa6NfWKZmdTRN7mnPnWWrw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Gxqj50v0foYFSx450MTgklJ9nonZ3WiQpE0+5Od2JdUih3U6BFfm3X3QK/OkoYLrO PCsMBnnU3Cgwos7SZIvVkqMrqBlRjKznSeb97WlOzOruPlRamte1NU7ifA1OU4Vm+u Ms5INTY7Q62pYZxIVCqAqzSJi7ojLPdVrdEjP7Ac= From: Brian Masney To: linus.walleij@linaro.org, sboyd@kernel.org, bjorn.andersson@linaro.org, andy.gross@linaro.org, marc.zyngier@arm.com Cc: shawnguo@kernel.org, dianders@chromium.org, linux-gpio@vger.kernel.org, nicolas.dechesne@linaro.org, niklas.cassel@linaro.org, david.brown@linaro.org, robh+dt@kernel.org, mark.rutland@arm.com, thierry.reding@gmail.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Subject: [PATCH v6 04/15] spmi: pmic-arb: convert to v2 irq interfaces to support hierarchical IRQ chips Date: Sat, 19 Jan 2019 15:42:41 -0500 Message-Id: <20190119204252.18370-5-masneyb@onstation.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190119204252.18370-1-masneyb@onstation.org> References: <20190119204252.18370-1-masneyb@onstation.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Convert the spmi-pmic-arb IRQ code to use the version 2 IRQ interface in order to support hierarchical IRQ chips. This is necessary so that spmi-gpio can be setup as a hierarchical IRQ chip with pmic-arb as the parent. IRQ chips in device tree should be usable from the start without the consumer having to make an additional call to gpio[d]_to_irq() to get the proper IRQ on the parent. The old qpnpint_irq_domain_map function would hardcode the handler as handle_level_irq, however qpnpint_irq_set_type would later override the handler. Properly set the handler when the IRQ is mapped. This new code doesn't return an error for IRQ_TYPE_NONE and preserves the existing behavior of using handle_level_irq since there are some broken device tree bindings that need to be corrected first. Driver was tested on a LG Nexus 5 (hammerhead) phone. Signed-off-by: Brian Masney --- The broken device tree bindings are corrected in this patch series and additional validation to the type field is added later in the series. Changes since v5: - Properly set handler to edge or level when the IRQ is mapped. Changes since v4: - None Changes since v3: - None Changes since v2: - Don't move pmic_gpio_of_match block. Use device_get_match_data instead of of_match_device. - Correct build warning on arm64: warning: cast from pointer to integer of different size drivers/spmi/spmi-pmic-arb.c | 67 +++++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 20 deletions(-) diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index 360b8218f322..928759242e42 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -666,7 +666,8 @@ static int qpnpint_get_irqchip_state(struct irq_data *d, return 0; } -static int qpnpint_irq_request_resources(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); u16 periph = hwirq_to_per(d->hwirq); @@ -692,27 +693,25 @@ static struct irq_chip pmic_arb_irqchip = { .irq_set_type = qpnpint_irq_set_type, .irq_set_wake = qpnpint_irq_set_wake, .irq_get_irqchip_state = qpnpint_get_irqchip_state, - .irq_request_resources = qpnpint_irq_request_resources, .flags = IRQCHIP_MASK_ON_SUSPEND, }; -static int qpnpint_irq_domain_dt_translate(struct irq_domain *d, - struct device_node *controller, - const u32 *intspec, - unsigned int intsize, - unsigned long *out_hwirq, - unsigned int *out_type) +static int qpnpint_irq_domain_translate(struct irq_domain *d, + struct irq_fwspec *fwspec, + unsigned long *out_hwirq, + unsigned int *out_type) { struct spmi_pmic_arb *pmic_arb = d->host_data; + 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", intspec[0], intspec[1], intspec[2]); - if (irq_domain_get_of_node(d) != controller) + if (irq_domain_get_of_node(d) != pmic_arb->spmic->dev.of_node) return -EINVAL; - if (intsize != 4) + if (fwspec->param_count != 4) return -EINVAL; if (intspec[0] > 0xF || intspec[1] > 0xFF || intspec[2] > 0x7) return -EINVAL; @@ -740,17 +739,43 @@ static int qpnpint_irq_domain_dt_translate(struct irq_domain *d, return 0; } -static int qpnpint_irq_domain_map(struct irq_domain *d, - unsigned int virq, - irq_hw_number_t hwirq) + +static void qpnpint_irq_domain_map(struct spmi_pmic_arb *pmic_arb, + struct irq_domain *domain, unsigned int virq, + irq_hw_number_t hwirq, unsigned int type) { - struct spmi_pmic_arb *pmic_arb = d->host_data; + irq_flow_handler_t handler; + + dev_dbg(&pmic_arb->spmic->dev, "virq = %u, hwirq = %lu, type = %u\n", + virq, hwirq, type); + + if (type & IRQ_TYPE_EDGE_BOTH) + handler = handle_edge_irq; + else + handler = handle_level_irq; + + irq_domain_set_info(domain, virq, hwirq, &pmic_arb_irqchip, pmic_arb, + handler, NULL, NULL); +} + +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 irq_fwspec *fwspec = data; + irq_hw_number_t hwirq; + unsigned int type; + int ret, i; + + ret = qpnpint_irq_domain_translate(domain, fwspec, &hwirq, &type); + if (ret) + return ret; - dev_dbg(&pmic_arb->spmic->dev, "virq = %u, hwirq = %lu\n", virq, hwirq); + for (i = 0; i < nr_irqs; i++) + qpnpint_irq_domain_map(pmic_arb, domain, virq + i, hwirq + i, + type); - irq_set_chip_and_handler(virq, &pmic_arb_irqchip, handle_level_irq); - irq_set_chip_data(virq, d->host_data); - irq_set_noprobe(virq); return 0; } @@ -1126,8 +1151,10 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = { }; static const struct irq_domain_ops pmic_arb_irq_domain_ops = { - .map = qpnpint_irq_domain_map, - .xlate = qpnpint_irq_domain_dt_translate, + .activate = qpnpint_irq_domain_activate, + .alloc = qpnpint_irq_domain_alloc, + .free = irq_domain_free_irqs_common, + .translate = qpnpint_irq_domain_translate, }; static int spmi_pmic_arb_probe(struct platform_device *pdev) -- 2.17.2