From patchwork Tue Jan 15 18:11:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tony Lindgren X-Patchwork-Id: 10764913 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 032206C5 for ; Tue, 15 Jan 2019 18:12:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E34612D466 for ; Tue, 15 Jan 2019 18:12:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D726D2D46E; Tue, 15 Jan 2019 18:12:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E8EE42D466 for ; Tue, 15 Jan 2019 18:12:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388046AbfAOSMH (ORCPT ); Tue, 15 Jan 2019 13:12:07 -0500 Received: from muru.com ([72.249.23.125]:33698 "EHLO muru.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729867AbfAOSMH (ORCPT ); Tue, 15 Jan 2019 13:12:07 -0500 Received: from hillo.muru.com (localhost [127.0.0.1]) by muru.com (Postfix) with ESMTP id 99CD98022; Tue, 15 Jan 2019 18:12:11 +0000 (UTC) From: Tony Lindgren To: linux-omap@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, Belisko Marek , Dmitry Lifshitz , "Dr. H. Nikolaus Schaller" , Jon Hunter , Keerthy , Laxman Dewangan , Nishanth Menon , Peter Ujfalusi , Richard Woodruff , Santosh Shilimkar , Tero Kristo , Thierry Reding Subject: [PATCH] ARM: OMAP5+: Fix inverted nirq pin interrupts with irq_set_type Date: Tue, 15 Jan 2019 10:11:55 -0800 Message-Id: <20190115181155.31155-1-tony@atomide.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Commit 83a86fbb5b56 ("irqchip/gic: Loudly complain about the use of IRQ_TYPE_NONE") started warning about incorrect dts usage for irqs. ARM GIC only supports active-high interrupts for SPI (Shared Peripheral Interrupts), and the Palmas PMIC by default is active-low. Palmas PMIC allows changing the interrupt polarity using register PALMAS_POLARITY_CTRL_INT_POLARITY, but configuring sys_nirq1 with a pull-down and setting PALMAS_POLARITY_CTRL_INT_POLARITY made the Palmas RTC interrupts stop working. This can be easily tested with kernel tools rtctest.c. Turns out the SoC inverts the sys_nirq pins for GIC as they do not go through a peripheral device but go directly to the MPUSS wakeupgen. I've verified this by muxing the interrupt line temporarily to gpio_wk16 instead of sys_nirq1. with a gpio, the interrupt works fine both active-low and active-high with the SoC internal pull configured and palmas polarity configured. But as sys_nirq1, the interrupt only works when configured ACTIVE_LOW for palmas, and ACTIVE_HIGH for GIC. Note that there was a similar issue earlier with tegra114 and palmas interrupt polarity that got fixed by commit df545d1cd01a ("mfd: palmas: Provide irq flags through DT/platform data"). However, the difference between omap5 and tegra114 is that tegra inverts the palmas interrupt twice, once when entering tegra PMC, and again when exiting tegra PMC to GIC. Let's fix the issue by adding a custom wakeupgen_irq_set_type() for wakeupgen and invert any interrupts with wrong polarity. Let's also warn about any non-sysnirq pins using wrong polarity. Note that we also need to update the dts for the level as IRQ_TYPE_NONE never has irq_set_type() called, and let's add some comments and use proper pin nameing to avoid more confusion later on. Cc: Belisko Marek Cc: Dmitry Lifshitz Cc: "Dr. H. Nikolaus Schaller" Cc: Jon Hunter Cc: Keerthy Cc: Laxman Dewangan Cc: Nishanth Menon Cc: Peter Ujfalusi Cc: Richard Woodruff Cc: Santosh Shilimkar Cc: Tero Kristo Cc: Thierry Reding Reported-by: Belisko Marek Signed-off-by: Tony Lindgren --- Marek, care to test this with any kernel between v4.17..v4.20? Current v5.0-rc1 seems to have some regmap_irq regression that needs separate fixes, I'll send a separate email about that. --- arch/arm/boot/dts/omap5-board-common.dtsi | 9 ++++-- arch/arm/boot/dts/omap5-cm-t54.dts | 12 +++++++- arch/arm/mach-omap2/omap-wakeupgen.c | 36 ++++++++++++++++++++++- 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/arch/arm/boot/dts/omap5-board-common.dtsi b/arch/arm/boot/dts/omap5-board-common.dtsi --- a/arch/arm/boot/dts/omap5-board-common.dtsi +++ b/arch/arm/boot/dts/omap5-board-common.dtsi @@ -317,7 +317,8 @@ palmas_sys_nirq_pins: pinmux_palmas_sys_nirq_pins { pinctrl-single,pins = < - OMAP5_IOPAD(0x068, PIN_INPUT_PULLUP | MUX_MODE0) /* sys_nirq1 */ + /* sys_nirq1 is pulled down as the SoC is inverting it for GIC */ + OMAP5_IOPAD(0x068, PIN_INPUT_PULLUP | MUX_MODE0) >; }; @@ -385,7 +386,8 @@ palmas: palmas@48 { compatible = "ti,palmas"; - interrupts = ; /* IRQ_SYS_1N */ + /* sys_nirq/ext_sys_irq pins get inverted at mpuss wakeupgen */ + interrupts = ; reg = <0x48>; interrupt-controller; #interrupt-cells = <2>; @@ -651,7 +653,8 @@ pinctrl-names = "default"; pinctrl-0 = <&twl6040_pins>; - interrupts = ; /* IRQ_SYS_2N cascaded to gic */ + /* sys_nirq/ext_sys_irq pins get inverted at mpuss wakeupgen */ + interrupts = ; /* audpwron gpio defined in the board specific dts */ diff --git a/arch/arm/boot/dts/omap5-cm-t54.dts b/arch/arm/boot/dts/omap5-cm-t54.dts --- a/arch/arm/boot/dts/omap5-cm-t54.dts +++ b/arch/arm/boot/dts/omap5-cm-t54.dts @@ -181,6 +181,13 @@ OMAP5_IOPAD(0x0042, PIN_INPUT_PULLDOWN | MUX_MODE6) /* llib_wakereqin.gpio1_wk15 */ >; }; + + palmas_sys_nirq_pins: pinmux_palmas_sys_nirq_pins { + pinctrl-single,pins = < + /* sys_nirq1 is pulled down as the SoC is inverting it for GIC */ + OMAP5_IOPAD(0x068, PIN_INPUT_PULLUP | MUX_MODE0) + >; + }; }; &omap5_pmx_core { @@ -414,8 +421,11 @@ palmas: palmas@48 { compatible = "ti,palmas"; - interrupts = ; /* IRQ_SYS_1N */ reg = <0x48>; + pinctrl-0 = <&palmas_sys_nirq_pins>; + pinctrl-names = "default"; + /* sys_nirq/ext_sys_irq pins get inverted at mpuss wakeupgen */ + interrupts = ; interrupt-controller; #interrupt-cells = <2>; ti,system-power-controller; diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -50,6 +50,9 @@ #define OMAP4_NR_BANKS 4 #define OMAP4_NR_IRQS 128 +#define SYS_NIRQ1_EXT_SYS_IRQ_1 7 +#define SYS_NIRQ2_EXT_SYS_IRQ_2 119 + static void __iomem *wakeupgen_base; static void __iomem *sar_base; static DEFINE_RAW_SPINLOCK(wakeupgen_lock); @@ -153,6 +156,37 @@ static void wakeupgen_unmask(struct irq_data *d) irq_chip_unmask_parent(d); } +/* + * The sys_nirq pins bypass peripheral modules and are wired directly + * to MPUSS wakeupgen. They get automatically inverted for GIC. + */ +static int wakeupgen_irq_set_type(struct irq_data *d, unsigned int type) +{ + bool inverted = false; + + switch (type) { + case IRQ_TYPE_LEVEL_LOW: + type &= ~IRQ_TYPE_LEVEL_MASK; + type |= IRQ_TYPE_LEVEL_HIGH; + inverted = true; + break; + case IRQ_TYPE_EDGE_FALLING: + type &= ~IRQ_TYPE_EDGE_BOTH; + type |= IRQ_TYPE_EDGE_RISING; + inverted = true; + break; + default: + break; + } + + if (inverted && d->hwirq != SYS_NIRQ1_EXT_SYS_IRQ_1 && + d->hwirq != SYS_NIRQ2_EXT_SYS_IRQ_2) + pr_warn("wakeupgen: irq%li polarity inverted in dts\n", + d->hwirq); + + return irq_chip_set_type_parent(d, type); +} + #ifdef CONFIG_HOTPLUG_CPU static DEFINE_PER_CPU(u32 [MAX_NR_REG_BANKS], irqmasks); @@ -446,7 +480,7 @@ static struct irq_chip wakeupgen_chip = { .irq_mask = wakeupgen_mask, .irq_unmask = wakeupgen_unmask, .irq_retrigger = irq_chip_retrigger_hierarchy, - .irq_set_type = irq_chip_set_type_parent, + .irq_set_type = wakeupgen_irq_set_type, .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND, #ifdef CONFIG_SMP .irq_set_affinity = irq_chip_set_affinity_parent,