Received: by 2002:a25:8b12:0:0:0:0:0 with SMTP id i18csp2709572ybl; Thu, 29 Aug 2019 11:47:28 -0700 (PDT) X-Google-Smtp-Source: APXvYqwwhKrKIKTszcwqLy7PSKgG5dQ0NvM/7lIvpdAU79tJrOU8R1eSzXk9W+sc+BSbcnjRKSsu X-Received: by 2002:a17:902:3204:: with SMTP id y4mr11720486plb.156.1567104448095; Thu, 29 Aug 2019 11:47:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1567104448; cv=none; d=google.com; s=arc-20160816; b=fnJVAkbz/k4qCUNPWtPYCmWW3Fw15135mzciZuHAUI5M6bCdsU84NeuV+NWFxqSbdt rorixyX7RHV09IuELkb7Fm1K4/e/d0d5MS4ftP0qHgZ7SdbHBSBeMX8873YYXS5QVDIQ Lh/2Ag76Y+KqlcVu1mBP3Zm1wrNEBp236G0eH8i843idb0wZSUSXQWRDBp0WV/kTOD1q tje/NN8D1L94anm2emrxWzh0jm2/f9HWJuEdIwebdgKtV7BcpR+ENyj5oJSntrNeEOLw WEAZahq+lyJnldhFCbJX6y8ZqWjXMSzhSN/js+n4tJjhzP4ndyJmjJYEVrwTafRyJbxd vjeA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dmarc-filter:dkim-signature:dkim-signature; bh=0U5hyyFd1SxTSXs+e5qmu9mRDlBbuXue+/xLKzVzfIU=; b=b+uyUcuq5fs0ZC5XtGsL/BBTj3hiCWLnXUR9DiAJ0oY1SKGmYnacMAR0WSUrHvA0K7 2N1BiT0iXIkP6Il3NEpRGQEhzRZeL5o4wPnIYwN/bayDSsZQLJo4Ah/yoXTsbqeOCKyh q8afueB2b+OXOgJhri6bMLy+MW12B3uV1JVa+syGOnhwpHyIDXOu9Wip9R4jfcfODghd Uz9qoDJYleH/6wTGnEjITCZ2kS97OHMc/u/3uu1iSBzWAj9aeSZf8YswW7TW++FH/DgH sr1u8U37nZ+KMq42rAqFvBlKhMJ4hZB+3OmrP9EgEarNr+e/aSEmwVGpf9DHuuyTZSGf 9A9g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@codeaurora.org header.s=default header.b=dh9Kt024; dkim=pass header.i=@codeaurora.org header.s=default header.b=W1Xr7uKc; 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 x26si3518117pfn.78.2019.08.29.11.47.12; Thu, 29 Aug 2019 11:47:28 -0700 (PDT) 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=pass header.i=@codeaurora.org header.s=default header.b=dh9Kt024; dkim=pass header.i=@codeaurora.org header.s=default header.b=W1Xr7uKc; 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 S1728431AbfH2SqE (ORCPT + 99 others); Thu, 29 Aug 2019 14:46:04 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:60572 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727867AbfH2SqE (ORCPT ); Thu, 29 Aug 2019 14:46:04 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 5AE2269729; Thu, 29 Aug 2019 18:12:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1567104362; bh=NeN4E6ZDwRBCdLKC0wxNI3H/ZmA0gyTLRM9b/Pm81zE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dh9Kt024EryacgO8qnE+9gVquDx+DFricK+M6P/3vzhkfVxNDqxf+59z6dr9X74A3 zfe3qN/r31VAzey3zoklmmtJm+RYl7kz0hAf0WnFY+bVneu3ACA9LHlngNRyMovHsL hePBKtFsrdID7SX/2h6ydKEbFYB3sRpQUJgDPFIQ= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on pdx-caf-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=ALL_TRUSTED,BAYES_00, DKIM_INVALID,DKIM_SIGNED,SPF_NONE autolearn=no autolearn_force=no version=3.4.0 Received: from codeaurora.org (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: ilina@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 97DC86895F; Thu, 29 Aug 2019 18:12:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1567102341; bh=NeN4E6ZDwRBCdLKC0wxNI3H/ZmA0gyTLRM9b/Pm81zE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=W1Xr7uKcxlsqNNIRblfR6+gWo8oIU6UQdeGiiVsn0afNghUlNl98SbU+tSJlNXlOr a87kHbC8jBnFS8ofI9wgMlF+3NPRyTY3nH+a0NXxc3TEHR/wTmJrMzjc9+LurBPD4K tcHBF4WEpXDYSnQiynyxvsDlbX51eR3zvE1sPJG0= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 97DC86895F Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=ilina@codeaurora.org From: Lina Iyer To: swboyd@chromium.org, evgreen@chromium.org, marc.zyngier@arm.com, linus.walleij@linaro.org Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, bjorn.andersson@linaro.org, mkshah@codeaurora.org, linux-gpio@vger.kernel.org, rnayak@codeaurora.org, Lina Iyer Subject: [PATCH RFC 06/14] drivers: irqchip: pdc: additionally set type in SPI config registers Date: Thu, 29 Aug 2019 12:11:55 -0600 Message-Id: <20190829181203.2660-7-ilina@codeaurora.org> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190829181203.2660-1-ilina@codeaurora.org> References: <20190829181203.2660-1-ilina@codeaurora.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org GPIOs that can be configured as wakeup are routed to the PDC wakeup interrupt controller and from there to the GIC interrupt controller. On some QCOM SoCs, the interface to the GIC for wakeup capable GPIOs have additional hardware registers that need to be configured as well to match the trigger type of the GPIO. This register interfaces the PDC to the GIC and therefore updated from the PDC driver. Typically, the firmware intializes the interface registers for the wakeup capable GPIOs with commonly used GPIO trigger type, but it is possible that a platform may want to use the GPIO differently. So, in addition to configuring the PDC, configure the interface registers as well. Signed-off-by: Lina Iyer --- drivers/irqchip/qcom-pdc.c | 93 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c index ad1faf634bcf..bf5f98bb4d2b 100644 --- a/drivers/irqchip/qcom-pdc.c +++ b/drivers/irqchip/qcom-pdc.c @@ -18,6 +18,8 @@ #include #include +#include + #define PDC_MAX_IRQS 126 #define PDC_MAX_GPIO_IRQS 256 @@ -35,10 +37,20 @@ struct pdc_pin_region { u32 cnt; }; +struct spi_cfg_regs { + union { + u64 start; + void __iomem *base; + }; + resource_size_t size; + bool scm_io; +}; + static DEFINE_RAW_SPINLOCK(pdc_lock); static void __iomem *pdc_base; static struct pdc_pin_region *pdc_region; static int pdc_region_cnt; +static struct spi_cfg_regs *spi_cfg; static void pdc_reg_write(int reg, u32 i, u32 val) { @@ -100,6 +112,57 @@ static void qcom_pdc_gic_unmask(struct irq_data *d) irq_chip_unmask_parent(d); } +static u32 __spi_pin_read(unsigned int pin) +{ + void __iomem *cfg_reg = spi_cfg->base + pin * 4; + u64 scm_cfg_reg = spi_cfg->start + pin * 4; + + if (spi_cfg->scm_io) { + unsigned int val; + + qcom_scm_io_readl(scm_cfg_reg, &val); + return val; + } else { + return readl(cfg_reg); + } +} + +static void __spi_pin_write(unsigned int pin, unsigned int val) +{ + void __iomem *cfg_reg = spi_cfg->base + pin * 4; + u64 scm_cfg_reg = spi_cfg->start + pin * 4; + + if (spi_cfg->scm_io) + qcom_scm_io_writel(scm_cfg_reg, val); + else + writel(val, cfg_reg); +} + +static int spi_configure_type(irq_hw_number_t hwirq, unsigned int type) +{ + int spi = hwirq - 32; + u32 pin = spi / 32; + u32 mask = BIT(spi % 32); + u32 val; + unsigned long flags; + + if (!spi_cfg) + return 0; + + if (pin * 4 > spi_cfg->size) + return -EFAULT; + + raw_spin_lock_irqsave(&pdc_lock, flags); + val = __spi_pin_read(pin); + val &= ~mask; + if (type & IRQ_TYPE_LEVEL_MASK) + val |= mask; + __spi_pin_write(pin, val); + raw_spin_unlock_irqrestore(&pdc_lock, flags); + + return 0; +} + /* * GIC does not handle falling edge or active low. To allow falling edge and * active low interrupts to be handled at GIC, PDC has an inverter that inverts @@ -137,7 +200,9 @@ enum pdc_irq_config_bits { static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) { int pin_out = d->hwirq; + int parent_hwirq = d->parent_data->hwirq; enum pdc_irq_config_bits pdc_type; + int ret; if (pin_out == GPIO_NO_WAKE_IRQ) return 0; @@ -168,6 +233,11 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) pdc_reg_write(IRQ_i_CFG, pin_out, pdc_type); + /* Additionally, configure (only) the GPIO in the f/w */ + ret = spi_configure_type(parent_hwirq, type); + if (ret) + return ret; + return irq_chip_set_type_parent(d, type); } @@ -354,6 +424,7 @@ static int pdc_setup_pin_mapping(struct device_node *np) static int qcom_pdc_init(struct device_node *node, struct device_node *parent) { struct irq_domain *parent_domain, *pdc_domain, *pdc_gpio_domain; + struct resource res; int ret; pdc_base = of_iomap(node, 0); @@ -384,6 +455,27 @@ static int qcom_pdc_init(struct device_node *node, struct device_node *parent) goto fail; } + ret = of_address_to_resource(node, 1, &res); + if (!ret) { + spi_cfg = kcalloc(1, sizeof(*spi_cfg), GFP_KERNEL); + if (!spi_cfg) { + ret = -ENOMEM; + goto remove; + } + spi_cfg->scm_io = of_find_property(node, + "qcom,scm-spi-cfg", NULL); + spi_cfg->size = resource_size(&res); + if (spi_cfg->scm_io) { + spi_cfg->start = res.start; + } else { + spi_cfg->base = ioremap(res.start, spi_cfg->size); + if (!spi_cfg->base) { + ret = -ENOMEM; + goto remove; + } + } + } + pdc_gpio_domain = irq_domain_create_hierarchy(parent_domain, IRQ_DOMAIN_FLAG_QCOM_PDC_WAKEUP, PDC_MAX_GPIO_IRQS, @@ -401,6 +493,7 @@ static int qcom_pdc_init(struct device_node *node, struct device_node *parent) remove: irq_domain_remove(pdc_domain); + kfree(spi_cfg); fail: kfree(pdc_region); iounmap(pdc_base); -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project