We are developing a product that has an i.MX8 mini SoC in it (imx8mm).
There is an IMU (MEMS motion sensor) connected to it, which we are reading using code running the M4 core. We use RPMSG to communicate with the product's main application, running on Linux on the A53 cores.
We already know from experience that the flow of data from the M4 to Linux via RPMSG prevent Linux from going to sleep. So we have code where we tell the M4 code to stop sending messages before we attempt to enter sleep. We then send it a command to resume sending messages after waking from sleep. This code works. We can wake it from sleep using the same button/interrupt we use to power our device on and off.
The next step, however, is to enter/leave sleep based on lack of motion, as determined by the IMU chip. I have already written the code so we can tell the M4 to stop sending messages until significant motion is detected, and then resume. This works great for temporarily suspending the data flow from the M4 to Linux, but the resumption of data flow does not cause Linux to wake from sleep.
It seems that the RPMSG activity is sufficient to prevent Linux from going to sleep, but they are not sufficient to wake it from sleep.
I don't yet know the reason why, but I assume the interrupt used to signal RPMSG data to Linux isn't able to wake the A53 cores from sleep. I assume I need to configure something in order to tell the IMX that its interrupt should be treated as a wakeup event, but I don't know what it is that I need to configure.
I already looked at application note AN12195 (low power audio) which talks about doing something very similar (for audio), but it doesn't include any code fragments. It only has a high-level description and links to Git repositories for massive components (like the Linux kernel), without specifying where the relevant bits of code or patch files may be found.
Update:
We've recently done some more testing, connecting to the M4's debug console and adding trace messages and it seems that the M4 core is being put to sleep along with the A53 cores.
If we start our application immediately after Linux boots, and it goes to sleep soon afterward (we've been using a 10s timeout for testing), and then move the device very soon afterward, then it will wake from sleep.
If, however, we allow the device to be running long enough for Linux to finish its startup sequences (including starting a few kernel device drivers that don't seem to start until after 60 seconds), then no luck. The device can not be awakened. Messages on the M4 console and GPIO activity from the M4 application both stop as well. It appears that the M4 has been put to sleep. So only an external interrupt (e.g. our power button) can wake it.
Similarly, if our device goes to sleep before Linux completes its startup, but remains asleep until after the kernel drivers all start themselves, kernel messages indicate that part of the sleep process waits for the kernel drivers to start, and then it goes completely to sleep. At which point, M4 activity also stops.
So the question is no longer how to get the M4 to generate an interrupt that will wake up Linux. That seems to be working fine. The question now is how to put the Linux cores (the A53) to sleep without putting the M4 to sleep.