drivers: irqchip: irq-qcom-mpm: rpm IRQ does not trigger when resuming on msm8953 soc

From: Bert Karwatzki
Date: Tue Jan 16 2024 - 07:43:29 EST


Since recently mpm node were added to the msm8996.dtsi devicetree:
https://lore.kernel.org/r/20231215-topic-mpm_dt-v1-2-c6636fc75ce3@xxxxxxxxxx
I tried to add support for the mpm interrupt controller to the msm8953.dtsi
device tree as both SOCs looked similar at first sight. The mpm-pin-map data
here was taken from the fairphone-fp3 downstream kernel (file
drivers/irqchip/qcom/mpm-8953.c):
Link: https://code.fairphone.com/projects/fairphone-3/gpl.html
The following patches were made for the following tree:
https://github.com/spasswolf/msm8953-linux/tree/v6.6.10_mpm

diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi
b/arch/arm64/boot/dts/qcom/msm8953.dtsi
index 566dd2197fd1..f7184b890d24 100644
--- a/arch/arm64/boot/dts/qcom/msm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi
@@ -633,6 +633,24 @@ memory {
reg = <0 0 0 0>;
};

+ mpm: interrupt-controller@601d4 {
+ compatible = "qcom,mpm";
+ qcom,rpm-msg-ram = <&apss_mpm>;
+ interrupts = <GIC_SPI 171 IRQ_TYPE_EDGE_RISING>;
+ mboxes = <&apcs 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ #power-domain-cells = <0>;
+ interrupt-parent = <&intc>;
+ qcom,mpm-pin-count = <96>;
+ qcom,mpm-pin-map = <2 184>, /* tsens_upper_lower_int */
+ <37 220>, /* qmp_usb3_lfps_rxterm_irq ->
ss_phy_irq */
+ <49 136>, /* qusb2phy_dpse_hv ->
hs_phy_irq*/
+ <53 72>, /* mdss_irq */
+ <58 136>, /* qusb2phy_dmse_hv ->
hs_phy_irq*/
+ <88 190>; /* ee0_krait_hlos_spmi_periph_irq
*/
+ };
+
pmu {
compatible = "arm,cortex-a53-pmu";
interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(8) |
IRQ_TYPE_LEVEL_HIGH)>;
@@ -694,11 +712,13 @@ CPU_PD7: power-domain-cpu7 {
CLUSTER0_PD: power-domain-cluster0 {
#power-domain-cells = <0>;
domain-idle-states = <&CLUSTER_RET>, <&CLUSTER_GDHS>,
<&CLUSTER_PC>;
+ power-domains = <&mpm>;
};

CLUSTER1_PD: power-domain-cluster1 {
#power-domain-cells = <0>;
domain-idle-states = <&CLUSTER_RET>, <&CLUSTER_GDHS>,
<&CLUSTER_PC>;
+ power-domains = <&mpm>;
};
};

@@ -958,6 +978,13 @@ soc: soc@0 {
rpm_msg_ram: sram@60000 {
compatible = "qcom,rpm-msg-ram";
reg = <0x00060000 0x8000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x00060000 0x8000>;
+
+ apss_mpm: sram@1d4 {
+ reg = <0x1d4 0x48>;
+ };
};

hsusb_phy: phy@79000 {
@@ -1012,8 +1039,8 @@ tsens0: thermal-sensor@4a9000 {
reg = <0x004a9000 0x1000>, /* TM */
<0x004a8000 0x1000>; /* SROT */
#qcom,sensors = <16>;
- interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts-extended = <&mpm 2 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 314
IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "uplow", "critical";
#thermal-sensor-cells = <1>;
};
@@ -1052,6 +1079,7 @@ tlmm: pinctrl@1000000 {
interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
gpio-ranges = <&tlmm 0 0 142>;
+ wakeup-parent = <&mpm>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
@@ -2176,7 +2204,7 @@ spmi_bus: spmi@200f000 {
<0x0200a000 0x2100>;
reg-names = "core", "chnls", "obsrvr", "intr", "cnfg";
interrupt-names = "periph_irq";
- interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts-extended = <&mpm 88 IRQ_TYPE_LEVEL_HIGH>;
qcom,ee = <0>;
qcom,channel = <0>;
interrupt-controller;
@@ -2247,8 +2275,8 @@ usb3: usb@70f8800 {
#size-cells = <1>;
ranges;

- interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts-extended = <&mpm 49 IRQ_TYPE_LEVEL_HIGH>,
+ <&mpm 37 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "hs_phy_irq", "ss_phy_irq";

clocks = <&gcc GCC_USB_PHY_CFG_AHB_CLK>,


I also added the msm_gpio_wakeirq_map (data again from downstream kernel)

diff --git a/drivers/pinctrl/qcom/pinctrl-msm8953.c
b/drivers/pinctrl/qcom/pinctrl-msm8953.c
index 998351bdfee1..2ea2c05aca9f 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm8953.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm8953.c
--- a/drivers/pinctrl/qcom/pinctrl-msm8953.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm8953.c
@@ -1790,6 +1790,20 @@ static const struct msm_pingroup msm8953_groups[] = {
SDC_QDSD_PINGROUP(sdc2_data, 0x109000, 9, 0),
};

+static const struct msm_gpio_wakeirq_map msm8953_mpm_map[] = {
+ {38, 3}, {1, 4}, {5, 5}, {9, 6}, {37, 8},
+ {36, 9}, {13, 10}, {35, 11}, {17, 12}, {21, 13},
+ {54, 14}, {34, 15}, {31, 16}, {58, 17}, {28, 18},
+ {42, 19}, {25, 20}, {12, 21}, {43, 22}, {44, 23},
+ {45, 24}, {46, 25}, {48, 26}, {65, 27}, {93, 28},
+ {97, 29}, {63, 30}, {70, 31}, {71, 32}, {72, 33},
+ {81, 34}, {85, 35}, {90, 36}, {67, 50}, {73, 51},
+ {74, 52}, {62, 53}, {59, 59}, {60, 60}, {61, 61},
+ {86, 62}, {87, 63}, {91, 64}, {129, 65}, {130, 66},
+ {131, 67}, {132, 68}, {133, 69}, {137, 70}, {138, 71},
+ {139, 72}, {140, 73}, {141, 74},
+};
+
static const struct msm_pinctrl_soc_data msm8953_pinctrl = {
.pins = msm8953_pins,
.npins = ARRAY_SIZE(msm8953_pins),
@@ -1798,6 +1812,9 @@ static const struct msm_pinctrl_soc_data msm8953_pinctrl =
{
.groups = msm8953_groups,
.ngroups = ARRAY_SIZE(msm8953_groups),
.ngpios = 142,
+ .wakeirq_map = msm8953_mpm_map,
+ .nwakeirq_map = ARRAY_SIZE(msm8953_mpm_map),
+ .wakeirq_dual_edge_errata = true,
};

The initial commit message of irq-qcom-mpm.c says
> - When SoC gets awake from sleep mode, the driver will receive an
> interrupt from RPM, so that it can replay interrupt for particular
> polarity.


The problem is that the IRQ does not trigger when suspending and resuming by
pressing the powerkey (tested on fairphone-fp3 running debian stable with the
linux-msm8953 mainline kernel):
$ cat /proc/interrupt | grep qcom_mpm
15: 0 0 0 0 0 0
0 0 GIC-0 203 Edge qcom_mpm

Is this a problem of the mpm driver or the mpm nodes? Or is this a misconfigured
RPM that does not trigger the interrupt when waking up? Do the mpm patches for
msm8996 sm6375 and qcm2290 already work on actual hardware? Is there
Documentation for the qcom RPM which describes how to enable this wakeup
interrupt?

Thanks in advance
Bert Karwatzki