Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable MPM interrupt controller #153

Draft
wants to merge 4 commits into
base: 6.6.10/main
Choose a base branch
from

Conversation

spasswolf
Copy link

@spasswolf spasswolf commented Jan 8, 2024

This enables the MPM interrupt controller which is supposed to be able to wake up the system from suspend. Next I'll put the IPA v2 patches on top of this to see if it's possible to receive SMS when suspended.

spasswolf and others added 3 commits January 8, 2024 17:59
The wakeirq_map data is taken from drivers/irqchip/qcom/mpm-8953.c in
the fairphone-fp3 downstream kernel.

Link: https://code.fairphone.com/projects/fairphone-3/gpl.html

Signed-off-by: Bert Karwatzki <spasswolf@web.de>
The MPM hardware is accessible from the ARM CPUs through a shared memory
region (RPM MSG RAM) which is also concurrently accessed by other kinds of
cores on the system like modem, ADSP etc.

Modeling this relation in a (somewhat) sane manner in the device tree
requires to

  - either present the MPM as a child of said memory region, which
    makes little sense, as a mapped memory carveout is not a bus.

  - define nodes which bleed their register spaces into one another

  - or passing their slice of the MSG RAM through a property

Go with the third option and add a way to map a region passed through the
"qcom,rpm-msg-ram" property as register space for the MPM interrupt
controller.

The current way of using 'reg' is preserved for backwards compatibility
reasons.

[ tglx: Massaged changelog ]

Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Acked-by: Shawn Guo <shawn.guo@linaro.org>
Link: https://lore.kernel.org/r/20230328-topic-msgram_mpm-v7-2-6ee2bfeaac2c@linaro.org
This adds a devicetree node for the mpm interrupt controller
and a node for the sram needed by the controller. The interrupt mapping
data is taken from the fairphone-fp3 downstream kernel
(drivers/irqchip/qcom/mpm-8953.c) and the mpm node for msm8996 was
used as a template.

Link: https://code.fairphone.com/projects/fairphone-3/gpl.html
Link: https://lore.kernel.org/r/20231215-topic-mpm_dt-v1-2-c6636fc75ce3@linaro.org

Signed-off-by: Bert Karwatzki <spasswolf@web.de>
@spasswolf
Copy link
Author

spasswolf commented Jan 9, 2024

Cherry-picked the ipa_legacy patches on top of this branch, no luck so far:

[   20.449796] platform 7940000.ipa: deferred probe pending
[   20.449868] qnoc-msm8953 400000.interconnect: sync_state() pending due to 7940000.ipa
[   20.454926] qnoc-msm8953 580000.interconnect: sync_state() pending due to 7940000.ipa
[   20.463382] psci-cpuidle-domain psci: sync_state() pending due to 7940000.ipa

Edit: For testing purposes I pulled in the old ipa v2 patches (which have been rebased to 6.6.0 in my msm8953_v6.6_2 branch where they are working) and got a similar result:

[   19.939841] platform 7940000.ipa: deferred probe pending
[   19.940032] psci-cpuidle-domain psci: sync_state() pending due to 7940000.ipa

Edit2: So it seems that doe to some issue ipa_probe is not even called here.

@z3ntu
Copy link

z3ntu commented Jan 9, 2024

Or you get -EPROBE_DEFER, if you want verbose messages CONFIG_DEBUG_DRIVER can be quite useful

@spasswolf
Copy link
Author

spasswolf commented Jan 9, 2024

No, I inserted a printk at the top of ipa_probe which does not show up in dmesg. Trying CONFIG_DEBUG_DRIVER next.

Tested with CONFIG_DEBUG_DRIVER=y and ipa legacy patch, the probe deferral seems to be caused by cpr:

$ dmesg | grep ipa
[    3.026885] bus: 'platform': add driver ipa
[    3.027142] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    3.027209] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    3.027269] platform 7940000.ipa: Added to deferred list
[    7.547264] devices_kset: Moving 7940000.ipa to end of list
[    7.547662] PM: Moving platform:7940000.ipa to end of list
[    7.547677] platform 7940000.ipa: Retrying from deferred list
[    7.548124] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    7.548159] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    7.548179] platform 7940000.ipa: Added to deferred list
[    7.653832] devices_kset: Moving 7940000.ipa to end of list
[    7.653862] PM: Moving platform:7940000.ipa to end of list
[    7.653882] platform 7940000.ipa: Retrying from deferred list
[    7.654464] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    7.654510] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    7.654534] platform 7940000.ipa: Added to deferred list
[    7.684795] devices_kset: Moving 7940000.ipa to end of list
[    7.684809] PM: Moving platform:7940000.ipa to end of list
[    7.684820] platform 7940000.ipa: Retrying from deferred list
[    7.685314] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    7.685354] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    7.685377] platform 7940000.ipa: Added to deferred list
[    7.709385] devices_kset: Moving 7940000.ipa to end of list
[    7.709404] PM: Moving platform:7940000.ipa to end of list
[    7.709417] platform 7940000.ipa: Retrying from deferred list
[    7.709967] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    7.710009] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    7.710031] platform 7940000.ipa: Added to deferred list
[    7.743706] devices_kset: Moving 7940000.ipa to end of list
[    7.743729] PM: Moving platform:7940000.ipa to end of list
[    7.743743] platform 7940000.ipa: Retrying from deferred list
[    7.762657] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    7.762721] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    7.762756] platform 7940000.ipa: Added to deferred list
[    7.795573] devices_kset: Moving 7940000.ipa to end of list
[    7.795584] PM: Moving platform:7940000.ipa to end of list
[    7.795595] platform 7940000.ipa: Retrying from deferred list
[    7.796108] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    7.796145] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    7.796167] platform 7940000.ipa: Added to deferred list
[    7.895810] devices_kset: Moving 7940000.ipa to end of list
[    7.895825] PM: Moving platform:7940000.ipa to end of list
[    7.895836] platform 7940000.ipa: Retrying from deferred list
[    7.896362] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    7.896396] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    7.896416] platform 7940000.ipa: Added to deferred list
[    7.938019] devices_kset: Moving 7940000.ipa to end of list
[    7.938031] PM: Moving platform:7940000.ipa to end of list
[    7.938046] platform 7940000.ipa: Retrying from deferred list
[    7.938897] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    7.938949] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    7.939024] platform 7940000.ipa: Added to deferred list
[    7.958288] devices_kset: Moving 7940000.ipa to end of list
[    7.958300] PM: Moving platform:7940000.ipa to end of list
[    7.958315] platform 7940000.ipa: Retrying from deferred list
[    7.959060] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    7.959116] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    7.959151] platform 7940000.ipa: Added to deferred list
[    7.983568] devices_kset: Moving 7940000.ipa to end of list
[    7.983587] PM: Moving platform:7940000.ipa to end of list
[    7.983602] platform 7940000.ipa: Retrying from deferred list
[    7.984427] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    7.984491] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    7.984527] platform 7940000.ipa: Added to deferred list
[    8.005424] devices_kset: Moving 7940000.ipa to end of list
[    8.005432] PM: Moving platform:7940000.ipa to end of list
[    8.005442] platform 7940000.ipa: Retrying from deferred list
[    8.005902] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    8.005938] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    8.005959] platform 7940000.ipa: Added to deferred list
[    8.017872] devices_kset: Moving 7940000.ipa to end of list
[    8.017881] PM: Moving platform:7940000.ipa to end of list
[    8.017890] platform 7940000.ipa: Retrying from deferred list
[    8.018358] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    8.018399] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    8.018420] platform 7940000.ipa: Added to deferred list
[    8.037707] devices_kset: Moving 7940000.ipa to end of list
[    8.037723] PM: Moving platform:7940000.ipa to end of list
[    8.037740] platform 7940000.ipa: Retrying from deferred list
[    8.038491] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    8.038543] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    8.038576] platform 7940000.ipa: Added to deferred list
[    8.049119] devices_kset: Moving 7940000.ipa to end of list
[    8.049127] PM: Moving platform:7940000.ipa to end of list
[    8.049137] platform 7940000.ipa: Retrying from deferred list
[    8.049649] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    8.049685] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    8.049710] platform 7940000.ipa: Added to deferred list
[    8.059453] devices_kset: Moving 7940000.ipa to end of list
[    8.059467] PM: Moving platform:7940000.ipa to end of list
[    8.059482] platform 7940000.ipa: Retrying from deferred list
[    8.060390] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    8.060446] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    8.060477] platform 7940000.ipa: Added to deferred list
[    8.089094] devices_kset: Moving 7940000.ipa to end of list
[    8.089117] PM: Moving platform:7940000.ipa to end of list
[    8.089134] platform 7940000.ipa: Retrying from deferred list
[    8.090056] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    8.090152] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    8.090199] platform 7940000.ipa: Added to deferred list
[    8.093504] devices_kset: Moving 7940000.ipa to end of list
[    8.093513] PM: Moving platform:7940000.ipa to end of list
[    8.093524] platform 7940000.ipa: Retrying from deferred list
[    8.094378] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    8.094430] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    8.094456] platform 7940000.ipa: Added to deferred list
[    8.106897] devices_kset: Moving 7940000.ipa to end of list
[    8.106906] PM: Moving platform:7940000.ipa to end of list
[    8.106915] platform 7940000.ipa: Retrying from deferred list
[    8.107378] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    8.107413] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    8.107434] platform 7940000.ipa: Added to deferred list
[    8.249805] devices_kset: Moving 7940000.ipa to end of list
[    8.249814] PM: Moving platform:7940000.ipa to end of list
[    8.249823] platform 7940000.ipa: Retrying from deferred list
[    8.250280] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    8.250318] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    8.250339] platform 7940000.ipa: Added to deferred list
[    8.258579] devices_kset: Moving 7940000.ipa to end of list
[    8.258602] PM: Moving platform:7940000.ipa to end of list
[    8.258618] platform 7940000.ipa: Retrying from deferred list
[    8.259437] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    8.259496] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    8.259528] platform 7940000.ipa: Added to deferred list
[    8.261553] devices_kset: Moving 7940000.ipa to end of list
[    8.261561] PM: Moving platform:7940000.ipa to end of list
[    8.261570] platform 7940000.ipa: Retrying from deferred list
[    8.262017] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    8.262055] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    8.262076] platform 7940000.ipa: Added to deferred list
[    8.375413] devices_kset: Moving 7940000.ipa to end of list
[    8.375428] PM: Moving platform:7940000.ipa to end of list
[    8.375442] platform 7940000.ipa: Retrying from deferred list
[    8.392290] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[    8.392338] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[    8.392361] platform 7940000.ipa: Added to deferred list
[   10.469793] devices_kset: Moving 7940000.ipa to end of list
[   10.469809] PM: Moving platform:7940000.ipa to end of list
[   10.469825] platform 7940000.ipa: Retrying from deferred list
[   10.470726] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[   10.470788] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[   10.470821] platform 7940000.ipa: Added to deferred list
[   10.484674] devices_kset: Moving 7940000.ipa to end of list
[   10.484687] PM: Moving platform:7940000.ipa to end of list
[   10.484701] platform 7940000.ipa: Retrying from deferred list
[   10.485552] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[   10.485619] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[   10.485653] platform 7940000.ipa: Added to deferred list
[   11.116137] devices_kset: Moving 7940000.ipa to end of list
[   11.116149] PM: Moving platform:7940000.ipa to end of list
[   11.116158] platform 7940000.ipa: Retrying from deferred list
[   11.116851] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[   11.116898] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[   11.116919] platform 7940000.ipa: Added to deferred list
[   11.120882] devices_kset: Moving 7940000.ipa to end of list
[   11.120892] PM: Moving platform:7940000.ipa to end of list
[   11.120906] platform 7940000.ipa: Retrying from deferred list
[   11.122557] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[   11.122617] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[   11.122642] platform 7940000.ipa: Added to deferred list
[   13.811900] devices_kset: Moving 7940000.ipa to end of list
[   13.811915] PM: Moving platform:7940000.ipa to end of list
[   13.811932] platform 7940000.ipa: Retrying from deferred list
[   13.812928] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[   13.813008] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[   13.813047] platform 7940000.ipa: Added to deferred list
[   13.830489] devices_kset: Moving 7940000.ipa to end of list
[   13.830502] PM: Moving platform:7940000.ipa to end of list
[   13.830519] platform 7940000.ipa: Retrying from deferred list
[   13.831381] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[   13.831450] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[   13.831485] platform 7940000.ipa: Added to deferred list
[   14.654372] Modules linked in: q6asm_dai q6voice_dai q6routing q6voice q6afe_clocks q6afe_dai q6asm q6adm q6mvm q6cvp q6cvs snd_q6dsp_common q6voice_common q6afe venus_dec venus_enc videobuf2_dma_contig q6core videobuf2_memops snd_soc_msm8916_digital venus_core v4l2_mem2mem snd_soc_core videobuf2_v4l2 snd_compress snd_pcm videobuf2_common snd_timer qcom_q6v5_mss qcom_wcnss_pil qcom_q6v5_pas videodev snd qcom_q6v5 qcom_pil_info mc soundcore qcom_sysmon ipa_legacy qcom_common
[   18.400465] platform 7940000.ipa: Relaxing link with cpu-perf-opp-table
[   18.400673] devices_kset: Moving 7940000.ipa to end of list
[   18.400687] PM: Moving platform:7940000.ipa to end of list
[   18.400701] platform 7940000.ipa: Retrying from deferred list
[   18.401550] bus: 'platform': __driver_probe_device: matched device 7940000.ipa with driver ipa
[   18.401604] platform 7940000.ipa: error -EPROBE_DEFER: wait for supplier /cpr-opp-table/opp-18048
[   18.401635] platform 7940000.ipa: Added to deferred list
[   18.401680] platform 7940000.ipa: deferred probe pending
[   18.401753] qnoc-msm8953 400000.interconnect: sync_state() pending due to 7940000.ipa
[   18.406811] qnoc-msm8953 580000.interconnect: sync_state() pending due to 7940000.ipa
[   18.415300] psci-cpuidle-domain psci: sync_state() pending due to 7940000.ipa

There seems to be a problem with the cpr init here ...

EDIT: No cpr init seems to work, but the messages did not show up because of the overly verbose CONFIG_DEBUG_DRIVER.

@spasswolf
Copy link
Author

The probe deferral is caused by this part of device_links_check_supplier:

int device_links_check_suppliers(struct device *dev)
{
	struct device_link *link;
	int ret = 0, fwnode_ret = 0;
	struct fwnode_handle *sup_fw;
	dev_info(dev, "calling %s\n", __func__);

	/*
	 * Device waiting for supplier to become available is not allowed to
	 * probe.
	 */
	mutex_lock(&fwnode_link_lock);
	sup_fw = fwnode_links_check_suppliers(dev->fwnode);
	dev_info(dev, "supplier = %pfwf\n", sup_fw);
	if (sup_fw) {
		if (!dev_is_best_effort(dev)) {
			fwnode_ret = -EPROBE_DEFER;
			dev_err_probe(dev, -EPROBE_DEFER,
				    "wait for supplier %pfwf\n", sup_fw);
		} else {
			fwnode_ret = -EAGAIN;
		}
	}
	mutex_unlock(&fwnode_link_lock);

I monitored this in the branch where IPA is working and found out that in that case the supplier is NULL:

[    6.103477] platform 7940000.ipa: calling device_links_check_suppliers
[    6.114008] platform 7940000.ipa: supplier = (null)
[    6.621728] ipa 7940000.ipa: IPA driver initialized
[    6.626994] ipa 7940000.ipa: IPA driver setup completed successfully
[   12.158439] ipa 7940000.ipa: received modem starting event
[   13.591062] ipa 7940000.ipa: received modem running event

@spasswolf
Copy link
Author

When I try to work around this with fw_devlink=permissive in the cmdline I get this

 dmesg | grep ipa
[    5.543666] OF: /soc@0/ipa@7940000: could not get #interconnect-cells for /psci/power-domain-cpu0
[    5.553923] ipa 7940000.ipa: of_icc_get() failed on path memory (-22)
[    5.563199] ipa: probe of 7940000.ipa failed with error -22

@vldly
Copy link
Member

vldly commented Jan 9, 2024

RPM interconnects on 6.6.0+ take extra cell. Did you adjust ipa node?

@spasswolf
Copy link
Author

No, I just pulled the patch from the 6.5 branch. Thank you, this is most likely the solution.

@spasswolf
Copy link
Author

spasswolf commented Jan 9, 2024

Adjusted the interconnects in the ipa node to:

interconnects = <&snoc MAS_IPA RPM_ACTIVE_TAG &bimc SLV_EBI RPM_ACTIVE_TAG>,
			     <&snoc MAS_IPA RPM_ACTIVE_TAG &snoc SLV_IMEM RPM_ACTIVE_TAG>,
			     <&bimc MAS_APPS_PROC RPM_ACTIVE_TAG &pcnoc SLV_IPA_CFG RPM_ACTIVE_TAG>;

ipa is running now (without fw_devlink=permissive):

[    4.079947] ipa 7940000.ipa: IPA driver initialized
[    4.090194] ipa 7940000.ipa: IPA driver setup completed successfully
[    8.267993] ipa 7940000.ipa: received modem starting event
[    9.676701] ipa 7940000.ipa: received modem running event

Should some of the _TAGS be other tags than RPM_ACTIVE_TAG?

@spasswolf
Copy link
Author

It's still not possible to wake the phone from suspend by calling it.

@M0Rf30 M0Rf30 marked this pull request as draft February 13, 2024 18:22
@vldly vldly added the enhancement New feature or request label Apr 30, 2024
#power-domain-cells = <0>;
interrupt-parent = <&intc>;
qcom,mpm-pin-count = <96>;
qcom,mpm-pin-map = <2 184>, /* tsens_upper_lower_int */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This offset IS confusing, but this is due to the the different mpm drivers in mainline and downstream kernel. The downstream kernel routes every interrupt through the mpm.

The irq numbers in mpm-pin-map should differ by 32 due to this, I think my template for this was

commit 09896da07315cce07b019ab00750c8a57e1b53a3
Author: Konrad Dybcio <konradybcio@kernel.org>
Date:   Fri Dec 15 01:01:09 2023 +0100

    arm64: dts: qcom: msm8996: Hook up MPM
    
    Wire up MPM and the interrupts it provides.
    
    Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
    Link: https://lore.kernel.org/r/20231215-topic-mpm_dt-v1-2-c6636fc75ce3@linaro.org
    Signed-off-by: Bjorn Andersson <andersson@kernel.org>

This has since then been reverted

commit 4f423c4cbe26d79d8974936eb01e0d6574c5d2ac
Author: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Date:   Wed Feb 21 01:07:21 2024 +0200

    Revert "arm64: dts: qcom: msm8996: Hook up MPM"
    
    Commit 09896da07315 ("arm64: dts: qcom: msm8996: Hook up MPM") has
    hooked up the MPM irq chip on the MSM8996 platform. However this causes
    my Dragonboard 820c crash during bootup (usually when probing IOMMUs).
    Revert the offending commit for now. Quick debug shows that making
    tlmm's wakeup-parent point to the MPM is enough to trigger the crash.
    
    Fixes: 09896da07315 ("arm64: dts: qcom: msm8996: Hook up MPM")
    Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
    Link: https://lore.kernel.org/r/20240221-msm8996-revert-mpm-v1-1-cdca9e30c9b4@linaro.org
    Signed-off-by: Bjorn Andersson <andersson@kernel.org>

I think I had the mentioned problem, too, (crash on boot when using mpm as tlmm's wakeup-parent) but solved it (as in avoiding the crash, wakeup is still not working). I will look into it but first have to rebase these to the newest branch, I havent't booted my FP3 into debian for a long time.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to find an example (i.e. an android kernel for msm8996 where the wakegic is used in the devicetree) but couldn't find one, so I tried to use the data from mpm-8953.c in my devicetree without shifting:

		qcom,mpm-pin-map = <2 216>,  /* tsens_upper_lower_int */
				   <37 252>, /* qmp_usb3_lfps_rxterm_irq -> ss_phy_irq */
				   <49 168>, /* qusb2phy_dpse_hv -> hs_phy_irq*/
				   <53 104>, /* mdss_irq */
				   <58 168>, /* qusb2phy_dmse_hv -> hs_phy_irq*/
				   <88 222>; /* ee0_krait_hlos_spmi_periph_irq */

and with this the kernel hangs when booting. I take this is a hint that the shift is correct.

interrupts = <GIC_SPI 171 IRQ_TYPE_EDGE_RISING>;
mboxes = <&apcs 1>;
interrupt-controller;
#interrupt-cells = <2>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

@spasswolf spasswolf Oct 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the downstream mpm controller "#interrupt-cells = <3>" only because it is used as interrupt-parent of the whole device-tree. In the examples in the mainline devicetree "qcom,mpm" is used with "#interrupt-cells = <2>", while the interrupt controller uses 3 cells (in sm6375.dtsi, qcm2290.dtsi).

Co-authored-by: Barnabás Czémán <barni2000@users.noreply.github.com>
@vldly
Copy link
Member

vldly commented Oct 26, 2024

It's still not possible to wake the phone from suspend by calling it.

This isn't because of MPM. MPM is responsible for deep sleep state which is hard to enter and will need a lot of changes.
To wake on phone call/message there should be at least enable_irq_wake on some modem IRQ, otherwise kernel disables it in suspend.

@spasswolf
Copy link
Author

spasswolf commented Oct 26, 2024

I've noticed that pressing the power button on my fairphone-fp3 (with this ms8953 kernel and debian stable(bookworm)) only suspends to idle (s2idle). I guess we need suspend-to-ram for the mpm do the waking-up.
Also I'm trying irq_set_irq_wake() on the modem irq, thanks for the hint.

@spasswolf
Copy link
Author

I was able to get working wakeup for calls (sms not tested, yet) with this (on top of 6.11.1/main from here).
The test with the src_port is required because otherwise the phone is woken up every few seconds.

commit 1c3d66bd9abd62ebae2eb49b39def118e2f16865
Author: Bert Karwatzki <spasswolf@web.de>
Date:   Fri Nov 8 01:09:00 2024 +0100

    qrtr: smd: Enable waking up for calls.
    
    This successfully wakes the fairphone-fp3 from s2idle when a call
    is incoming. This is an adaption and extension of Caleb Connolly's patch
    for glink. It recognizes incoming calls and messages by examining the
    src_port of the qrtr protocol and sends a wakup event in these cases. I
    don't no if the port number (which are reported by qrtr-lookup) are
    universal so this is probably not portable, yet.
    
    Link: https://lore.kernel.org/all/20230117142414.983946-1-caleb.connolly@linaro.org/
    Link: https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/694
    
    Signed-off-by: Bert Karwatzki <spasswolf@web.de>

diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c
index 43f601c84b4f..5a9b5d8a64f1 100644
--- a/drivers/rpmsg/qcom_smd.c
+++ b/drivers/rpmsg/qcom_smd.c
@@ -1074,6 +1074,7 @@ static int qcom_smd_create_device(struct qcom_smd_channel *channel)
 	struct qcom_smd_device *qsdev;
 	struct rpmsg_device *rpdev;
 	struct qcom_smd_edge *edge = channel->edge;
+	int ret;
 
 	dev_dbg(&edge->dev, "registering '%s'\n", channel->name);
 
@@ -1097,7 +1098,19 @@ static int qcom_smd_create_device(struct qcom_smd_channel *channel)
 	rpdev->dev.parent = &edge->dev;
 	rpdev->dev.release = qcom_smd_release_device;
 
-	return rpmsg_register_device(rpdev);
+	ret = rpmsg_register_device(rpdev);
+	/*
+	 * Declare all channels as wakeup capable, but don't enable
+	 * waking up by default.
+	 *
+	 * Userspace may wish to be woken up for incoming messages on a
+	 * specific channel, for example to handle incoming calls or SMS
+	 * messages on the IPCRTR channel. This can be done be enabling
+	 * the wakeup source via sysfs.
+	 */
+	device_set_wakeup_capable(&rpdev->dev, true);
+
+	return ret;
 }
 
 static int qcom_smd_create_chrdev(struct qcom_smd_edge *edge)
@@ -1415,7 +1428,7 @@ static int qcom_smd_parse_edge(struct device *dev,
 	}
 
 	ret = devm_request_irq(dev, irq,
-			       qcom_smd_edge_intr, IRQF_TRIGGER_RISING,
+			       qcom_smd_edge_intr, IRQF_NO_SUSPEND | IRQF_TRIGGER_RISING,
 			       node->name, edge);
 	if (ret) {
 		dev_err(dev, "failed to request smd irq\n");
diff --git a/net/qrtr/af_qrtr.c b/net/qrtr/af_qrtr.c
index 41ece61eb57a..050e528664dd 100644
--- a/net/qrtr/af_qrtr.c
+++ b/net/qrtr/af_qrtr.c
@@ -429,10 +429,13 @@ static void qrtr_node_assign(struct qrtr_node *node, unsigned int nid)
  * @ep: endpoint handle
  * @data: data pointer
  * @len: size of data in bytes
+ * @src_port: report src_port back to smd callback function
+ *            to decide about wakeup 
  *
  * Return: 0 on success; negative error code on failure
  */
-int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
+int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len,
+		       u32 *src_port)
 {
 	struct qrtr_node *node = ep->node;
 	const struct qrtr_hdr_v1 *v1;
@@ -497,6 +500,9 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
 		goto err;
 	}
 
+	if (src_port)
+		*src_port = cb->src_port;
+
 	if (cb->dst_port == QRTR_PORT_CTRL_LEGACY)
 		cb->dst_port = QRTR_PORT_CTRL;
 
diff --git a/net/qrtr/mhi.c b/net/qrtr/mhi.c
index 69f53625a049..3159ba3d4870 100644
--- a/net/qrtr/mhi.c
+++ b/net/qrtr/mhi.c
@@ -28,7 +28,7 @@ static void qcom_mhi_qrtr_dl_callback(struct mhi_device *mhi_dev,
 		return;
 
 	rc = qrtr_endpoint_post(&qdev->ep, mhi_res->buf_addr,
-				mhi_res->bytes_xferd);
+				mhi_res->bytes_xferd, NULL);
 	if (rc == -EINVAL)
 		dev_err(qdev->dev, "invalid ipcrouter packet\n");
 }
diff --git a/net/qrtr/qrtr.h b/net/qrtr/qrtr.h
index 3f2d28696062..2c61bc25e69f 100644
--- a/net/qrtr/qrtr.h
+++ b/net/qrtr/qrtr.h
@@ -27,7 +27,8 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int nid);
 
 void qrtr_endpoint_unregister(struct qrtr_endpoint *ep);
 
-int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len);
+int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len,
+		       u32 *src_port);
 
 int qrtr_ns_init(void);
 
diff --git a/net/qrtr/smd.c b/net/qrtr/smd.c
index c91bf030fbc7..b7be99b23286 100644
--- a/net/qrtr/smd.c
+++ b/net/qrtr/smd.c
@@ -7,6 +7,7 @@
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/rpmsg.h>
+#include <linux/pm_wakeup.h>
 
 #include "qrtr.h"
 
@@ -22,17 +23,23 @@ static int qcom_smd_qrtr_callback(struct rpmsg_device *rpdev,
 {
 	struct qrtr_smd_dev *qdev = dev_get_drvdata(&rpdev->dev);
 	int rc;
+	u32 src_port = 0;
 
 	if (!qdev)
 		return -EAGAIN;
 
-	rc = qrtr_endpoint_post(&qdev->ep, data, len);
+	rc = qrtr_endpoint_post(&qdev->ep, data, len, &src_port);
 	if (rc == -EINVAL) {
 		dev_err(qdev->dev, "invalid ipcrouter packet\n");
 		/* return 0 to let smd drop the packet */
 		rc = 0;
+		return rc;
 	}
 
+	if (src_port == 39 || // Voice service port given by qrtr-lookup. This works!
+	    src_port == 52)   // Wirless messaging service port given by qrtr-lookup. Not tested yet.
+		pm_wakeup_ws_event(rpdev->dev.power.wakeup, 0, true);
+
 	return rc;
 }
 
diff --git a/net/qrtr/tun.c b/net/qrtr/tun.c
index 304b41fea5ab..13def05be3e8 100644
--- a/net/qrtr/tun.c
+++ b/net/qrtr/tun.c
@@ -105,7 +105,7 @@ static ssize_t qrtr_tun_write_iter(struct kiocb *iocb, struct iov_iter *from)
 		return -EFAULT;
 	}
 
-	ret = qrtr_endpoint_post(&tun->ep, kbuf, len);
+	ret = qrtr_endpoint_post(&tun->ep, kbuf, len, NULL);
 
 	kfree(kbuf);
 	return ret < 0 ? ret : len;

@z3ntu
Copy link

z3ntu commented Nov 8, 2024

That's pretty awesome! :)

@spasswolf
Copy link
Author

spasswolf commented Nov 8, 2024

This has to be enabled in sysfs like this (remoteproc0 can also be remoteproc{1,2} here, this seems to change without reason)

echo enabled > /sys/devices/platform/soc@0/4080000.remoteproc/remoteproc/remoteproc0/remoteproc0\:smd-edge/remoteproc0\:smd-edge.IPCRTR.-1.-1/power/wakeup

@z3ntu: As you have acccess to a lot of different phone models, can you check if the qrtr ports for voice and messaging are universal using qrtr-lookup?

Also, this is not the way the device is woken up in the downstream kernel, there the smd-edge interrupts do not have the flag IRQF_NO_SUSPEND.

@vldly
Copy link
Member

vldly commented Nov 8, 2024

Also, this is not the way the device is woken up in the downstream kernel, there the smd-edge interrupts do not have the flag IRQF_NO_SUSPEND.

There is in smd_init_dt.c. smd.c is driver from mainline.

@spasswolf
Copy link
Author

Ah, thanks I had that mixed up.

@spasswolf
Copy link
Author

Receiving SMS works, too.

@barni2000
Copy link
Member

barni2000 commented Nov 10, 2024

It should be definitely sent to upstream (at least pinctrl part).

@spasswolf
Copy link
Author

The working wakeup for calls and SMS is done without mpm, it's just the qrtr callback called by the smd interrupt handler which is waking up the phone from s2idle.

@spasswolf
Copy link
Author

The qrtr ports are probably not universal, qrtr-lookup receives the port values from an AF_QIPCRTR socket (in qrtr-1.1/src/lookup.c). If they are indeed not universal the ports needed for wakeup could be specified in the devicetree, perhaps as properties of the smd-edge for the modem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants