I understand the issue now. After kernel_shutdown_prepare() is called
from kernel_power_off() you are no longer allowed to sleep. I couldn't
find this documented anywhere but it appears to be assumed and probably
obvious to anyone working in this part of the code.
What this also means you are no longer allowed to grab a mutex. This
means if another task has stopped while holding the i2c mutex then an
i2c PMIC will never be able to shutdown the device. There are a lot of
devices out there depending on an i2c PMIC for shutdown, so kind of
surprised me that this issue exists. The easy/ugly fix is just to force
everyone off the i2c bus before calling kernel_shutdown_prepare(). This
solved my problem, but not a great general solution.
On 02/18/2017 12:02 PM, James Maki wrote:
Hi,
I have an TI am335x that is using a i2c PMIC with pm_power_off hook
which locks up on shutdown. The pm_power_off hook gets stuck obtaining
i2c_lock_adapter(). The holder of the lock is the lis3lv02d
accelerometer which never releases it.
I do not think there is an issue in lis3lv02d. I think this is a
general issue with i2c since other drivers have the same design. What
I don't have is clear understanding of if/when/how i2c_transfer() can
be called post kernel_power_off(). Is it possible to call
i2c_transfer() at this point. I have tried calling schedule() and
msleep() inside of kernel_power_off() after syscore_shutdown(). It
looks like interrupts are enabled and I can still schedule at this
point. So how is it possible that lis3lv02d is never able to exit the
i2c_transfer()? Is there some other lock inside i2c_transfer that it
is blocking on?
Is it possible that the process which had the accelerometer open has
exited while holding the i2c lock. Is it even possible for a device to
shutdown or file to close while holding a lock in the kernel?
I looked at adding a lis3lv02d_i2c_shutdown, but that was too late in
the process already and the lis3lv02d was already stuck. Is there a
very early place during shutdown that I can kick everyone off the i2c
bus? Obviously this might not be the best general solution, but my
concern right now is fixing the problem on this particular system first.
-James
--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html