Skip to content

Commit d024369

Browse files
committed
ARM: OMAP5+: Fix inverted nirq pin interrupts with irq_set_type
Commit 83a86fb ("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 df545d1 ("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 <marek.belisko@gmail.com> Cc: Dmitry Lifshitz <lifshitz@compulab.co.il> Cc: "Dr. H. Nikolaus Schaller" <hns@goldelico.com> Cc: Jon Hunter <jonathanh@nvidia.com> Cc: Keerthy <j-keerthy@ti.com> Cc: Laxman Dewangan <ldewangan@nvidia.com> Cc: Nishanth Menon <nm@ti.com> Cc: Peter Ujfalusi <peter.ujfalusi@ti.com> Cc: Richard Woodruff <r-woodruff2@ti.com> Cc: Santosh Shilimkar <ssantosh@kernel.org> Cc: Tero Kristo <t-kristo@ti.com> Cc: Thierry Reding <treding@nvidia.com> Cc: stable@vger.kernel.org # v4.17+ Reported-by: Belisko Marek <marek.belisko@gmail.com> Signed-off-by: Tony Lindgren <tony@atomide.com>
1 parent 063c20e commit d024369

File tree

3 files changed

+52
-5
lines changed

3 files changed

+52
-5
lines changed

arch/arm/boot/dts/omap5-board-common.dtsi

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,8 @@
317317

318318
palmas_sys_nirq_pins: pinmux_palmas_sys_nirq_pins {
319319
pinctrl-single,pins = <
320-
OMAP5_IOPAD(0x068, PIN_INPUT_PULLUP | MUX_MODE0) /* sys_nirq1 */
320+
/* sys_nirq1 is pulled down as the SoC is inverting it for GIC */
321+
OMAP5_IOPAD(0x068, PIN_INPUT_PULLUP | MUX_MODE0)
321322
>;
322323
};
323324

@@ -385,7 +386,8 @@
385386

386387
palmas: palmas@48 {
387388
compatible = "ti,palmas";
388-
interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* IRQ_SYS_1N */
389+
/* sys_nirq/ext_sys_irq pins get inverted at mpuss wakeupgen */
390+
interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_LOW>;
389391
reg = <0x48>;
390392
interrupt-controller;
391393
#interrupt-cells = <2>;
@@ -651,7 +653,8 @@
651653
pinctrl-names = "default";
652654
pinctrl-0 = <&twl6040_pins>;
653655

654-
interrupts = <GIC_SPI 119 IRQ_TYPE_NONE>; /* IRQ_SYS_2N cascaded to gic */
656+
/* sys_nirq/ext_sys_irq pins get inverted at mpuss wakeupgen */
657+
interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_LOW>;
655658

656659
/* audpwron gpio defined in the board specific dts */
657660

arch/arm/boot/dts/omap5-cm-t54.dts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,13 @@
181181
OMAP5_IOPAD(0x0042, PIN_INPUT_PULLDOWN | MUX_MODE6) /* llib_wakereqin.gpio1_wk15 */
182182
>;
183183
};
184+
185+
palmas_sys_nirq_pins: pinmux_palmas_sys_nirq_pins {
186+
pinctrl-single,pins = <
187+
/* sys_nirq1 is pulled down as the SoC is inverting it for GIC */
188+
OMAP5_IOPAD(0x068, PIN_INPUT_PULLUP | MUX_MODE0)
189+
>;
190+
};
184191
};
185192

186193
&omap5_pmx_core {
@@ -414,8 +421,11 @@
414421

415422
palmas: palmas@48 {
416423
compatible = "ti,palmas";
417-
interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* IRQ_SYS_1N */
418424
reg = <0x48>;
425+
pinctrl-0 = <&palmas_sys_nirq_pins>;
426+
pinctrl-names = "default";
427+
/* sys_nirq/ext_sys_irq pins get inverted at mpuss wakeupgen */
428+
interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_LOW>;
419429
interrupt-controller;
420430
#interrupt-cells = <2>;
421431
ti,system-power-controller;

arch/arm/mach-omap2/omap-wakeupgen.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@
5050
#define OMAP4_NR_BANKS 4
5151
#define OMAP4_NR_IRQS 128
5252

53+
#define SYS_NIRQ1_EXT_SYS_IRQ_1 7
54+
#define SYS_NIRQ2_EXT_SYS_IRQ_2 119
55+
5356
static void __iomem *wakeupgen_base;
5457
static void __iomem *sar_base;
5558
static DEFINE_RAW_SPINLOCK(wakeupgen_lock);
@@ -153,6 +156,37 @@ static void wakeupgen_unmask(struct irq_data *d)
153156
irq_chip_unmask_parent(d);
154157
}
155158

159+
/*
160+
* The sys_nirq pins bypass peripheral modules and are wired directly
161+
* to MPUSS wakeupgen. They get automatically inverted for GIC.
162+
*/
163+
static int wakeupgen_irq_set_type(struct irq_data *d, unsigned int type)
164+
{
165+
bool inverted = false;
166+
167+
switch (type) {
168+
case IRQ_TYPE_LEVEL_LOW:
169+
type &= ~IRQ_TYPE_LEVEL_MASK;
170+
type |= IRQ_TYPE_LEVEL_HIGH;
171+
inverted = true;
172+
break;
173+
case IRQ_TYPE_EDGE_FALLING:
174+
type &= ~IRQ_TYPE_EDGE_BOTH;
175+
type |= IRQ_TYPE_EDGE_RISING;
176+
inverted = true;
177+
break;
178+
default:
179+
break;
180+
}
181+
182+
if (inverted && d->hwirq != SYS_NIRQ1_EXT_SYS_IRQ_1 &&
183+
d->hwirq != SYS_NIRQ2_EXT_SYS_IRQ_2)
184+
pr_warn("wakeupgen: irq%li polarity inverted in dts\n",
185+
d->hwirq);
186+
187+
return irq_chip_set_type_parent(d, type);
188+
}
189+
156190
#ifdef CONFIG_HOTPLUG_CPU
157191
static DEFINE_PER_CPU(u32 [MAX_NR_REG_BANKS], irqmasks);
158192

@@ -446,7 +480,7 @@ static struct irq_chip wakeupgen_chip = {
446480
.irq_mask = wakeupgen_mask,
447481
.irq_unmask = wakeupgen_unmask,
448482
.irq_retrigger = irq_chip_retrigger_hierarchy,
449-
.irq_set_type = irq_chip_set_type_parent,
483+
.irq_set_type = wakeupgen_irq_set_type,
450484
.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND,
451485
#ifdef CONFIG_SMP
452486
.irq_set_affinity = irq_chip_set_affinity_parent,

0 commit comments

Comments
 (0)