From: Esben Haabendal <esben@geanix.com>
To: "Jonathan Cameron" <jic23@kernel.org>
Cc: "Lars-Peter Clausen" <lars@metafoo.de>,
"Rob Herring" <robh@kernel.org>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Conor Dooley" <conor+dt@kernel.org>,
"Martin Kepplinger" <martink@posteo.de>,
"Sean Nyekjaer" <sean@geanix.com>,
"David Lechner" <dlechner@baylibre.com>,
"Nuno Sá" <nuno.sa@analog.com>,
"Andy Shevchenko" <andy@kernel.org>,
"Martin Kepplinger" <martin.kepplinger@theobroma-systems.com>,
"Christoph Muellner" <christoph.muellner@theobroma-systems.com>,
linux-iio@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v8 9/9] iio: accel: mma8452: Support interrupt sharing
Date: Mon, 14 Sep 2026 09:15:55 +0200 [thread overview]
Message-ID: <87y0d4pal0.fsf@geanix.com> (raw)
In-Reply-To: <20260914002203.5ca07dd0@jic23-hlaptop>
"Jonathan Cameron" <jic23@kernel.org> writes:
> On Mon, 07 Sep 2026 16:51:04 +0200
> Esben Haabendal <esben@geanix.com> wrote:
>
>> Adding support for sharing interrupt line with other device requires the
>> interrupt handler to handle runtime PM suspension properly, ignoring the
>> irq if the device is suspended (maybe even off). And while at it, we use
>> the PM reference to ensure we do not get suspended while processing an irq.
>>
>> In order to prevent the chip from raising irq while suspended (that is when
>> using fixed regulator, where suspend just means setting the device in
>> STANDBY mode), we disable all interrupt sources by clearing CTRL_REG4, and
>> then restores the value again when resuming.
>>
>> With that in place, it is safe to add the IRQF_SHARED flag.
>>
>> Keep in mind that the device by default is using push-pull for the irq pin,
>> which might require additional hardware design to allow interrupt sharing.
>>
>> Signed-off-by: Esben Haabendal <esben@geanix.com>
>> ---
>> drivers/iio/accel/mma8452.c | 67 +++++++++++++++++++++++++++++++++++++++------
>> 1 file changed, 58 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c
>> index fda29df5d109..e521dca37f76 100644
>> --- a/drivers/iio/accel/mma8452.c
>> +++ b/drivers/iio/accel/mma8452.c
>> @@ -120,6 +120,7 @@
>> * @sleep_val: time in ms to sleep while waiting for drdy
>> * @ctrl_reg1: CTRL_REG1 register shadow value
>> * @data_cfg: DATA_CFG register shadow value
>> + * @ctrl_reg4: CTRL_REG4 register value to restore on resume
>> * @open_drain: true for irq pin in open-drain mode
>> */
>> struct mma8452_data {
>> @@ -138,6 +139,7 @@ struct mma8452_data {
>> int sleep_val;
>> u8 ctrl_reg1;
>> u8 data_cfg;
>> + u8 ctrl_reg4;
>> bool open_drain;
>> };
>>
>> @@ -1083,15 +1085,21 @@ static irqreturn_t mma8452_interrupt(int irq, void *p)
>> {
>> struct iio_dev *indio_dev = p;
>> struct mma8452_data *data = iio_priv(indio_dev);
>> + struct device *dev = &data->client->dev;
>> irqreturn_t ret = IRQ_NONE;
>> + int pm_status;
>> int src;
>>
>> + pm_status = pm_runtime_get_if_active(dev);
>
> Sashiko raises the question of what happens if you actually get an error
> return from this. You may be deliberately ignoring those, but if
> so add a comment.
Yes, sounds like a good idea.
> The fun race around tear down is worth considering in particular (see
> sashiko comment).
I will look into that. Although very unlikely, it does sound like a real
issue that *could* occur.
Adding a boolean flag (remove_in_progress = true) to the mma8452_data
struct, and set that in mma8452_remove() before disabling runtime pm
seems like a KISS solution. Should we be returning IRQ_HANDLED or
IRQ_NONE in that case? There is no IRQ_MAYBE return value :D
>> + if (pm_status == 0)
>> + return IRQ_NONE; /* device is powered down */
>
>> @@ -1784,29 +1796,62 @@ static void mma8452_remove(struct i2c_client *client)
>> #ifdef CONFIG_PM
>> static int mma8452_runtime_suspend(struct device *dev)
>> {
>> - struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
>> + struct i2c_client *client = to_i2c_client(dev);
>> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
>> struct mma8452_data *data = iio_priv(indio_dev);
>> int ret;
>>
>> - scoped_guard(mutex, &data->lock)
>> - ret = mma8452_standby(data);
>> + guard(mutex)(&data->lock);
> Mixing guards...
Yes, I know. Resolving that turned out to be a bit more painful than I
thought. I do have that resolved in the next series I keep on talking
about. But distilling that as a separate patch for adding to this series
turned out to be impossible, as it relies on some of the other work,
like refactoring of the ACTIVE/STANDBY state handling (synchronization),
and most importantly, the switch to using regmap caching to properly
handle restoring of register values on resume.
I am therefore hoping that we can find some way to agree on things here,
and then properly resolve it in the next series...
For what it is worth, in this very specific case, the only guard used is
first in the LIFO order, and will therefore be executed in exactly the
right order on exit, as it will run after all the goto cleanup, just as
the LIFO cleanup order requires.
Obviously a fragile and undesirable way of doing error handling, but it
will go away again in the next series where I will eliminate the goto
error handling in mma8452_runtime_suspend().
>> +
>> + ret = i2c_smbus_read_byte_data(client, MMA8452_CTRL_REG4);
>> if (ret < 0) {
>> - dev_err(dev, "powering off device failed\n");
>> + dev_warn(dev, "backing up CTRL_REG4 failed\n");
>> return -EAGAIN;
>> + } else
>> + data->ctrl_reg4 = ret;
>> +
>> + ret = i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG4, 0);
>> + if (ret) {
>> + dev_warn(dev, "disabling interrupt sources (CTRL_REG4) failed\n");
>> + return -EAGAIN;
>> + }
>> +
>> + ret = mma8452_standby(data);
>> + if (ret < 0) {
>> + dev_err(dev, "transition to STANDBY mode failed\n");
>> + ret = -EAGAIN;
>> + goto out_restore_ctrl_reg4;
>
> and goto is explicitly advised against in the docs in cleanup.h
> You need to restructure the code to avoid that, potentially via
> a helper function.
I agree. See above.
>> }
>>
>> + /*
>> + * Interrupt line should be deasserted now, so we just need ensure any
>> + * mid-flight irq is completed (will return IRQ_NONE due to
>> + * pm_status==0).
>> + */
>> + if (client->irq)
>> + synchronize_irq(client->irq);
>> +
>> ret = regulator_bulk_disable(ARRAY_SIZE(data->regs), data->regs);
>> if (ret) {
>> dev_err(dev, "failed to disable regulators\n");
>> - return ret;
>> + goto out_active;
>> }
>>
>> return 0;
>> +
>> +out_active:
>> + if (mma8452_active(data))
>> + dev_warn(dev, "failed to switch back to ACTIVE mode\n");
>> +out_restore_ctrl_reg4:
>> + if (i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG4, data->ctrl_reg4))
>> + dev_warn(dev, "restoring CTRL_REG4 failed\n");
>> + return ret;
>> }
>>
>> static int mma8452_runtime_resume(struct device *dev)
>> {
>> - struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
>> + struct i2c_client *client = to_i2c_client(dev);
>> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
>> struct mma8452_data *data = iio_priv(indio_dev);
>> int ret, sleep_val;
>>
>> @@ -1820,6 +1865,10 @@ static int mma8452_runtime_resume(struct device *dev)
>> if (ret)
>> goto runtime_resume_failed;
>>
>> + ret = i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG4, data->ctrl_reg4);
>> + if (ret)
>> + goto runtime_resume_failed;
>> +
>> ret = mma8452_active(data);
>> if (ret < 0)
>> goto runtime_resume_failed;
>>
prev parent reply other threads:[~2026-09-14 7:16 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-07 14:50 [PATCH v8 0/9] io: accel: mma8452: Allow open drain interrupt pin configuration Esben Haabendal
2026-09-07 14:50 ` [PATCH v8 1/9] dt-bindings: iio: accel: mma8452: Add drive-open-drain Esben Haabendal
2026-09-07 14:50 ` [PATCH v8 2/9] iio: accel: mma8452: Fix use-after-free bug in error error path Esben Haabendal
2026-09-13 23:09 ` Jonathan Cameron
2026-09-14 6:49 ` Esben Haabendal
2026-09-07 14:50 ` [PATCH v8 3/9] iio: accel: mma8452: Optimize struct mma8452_data member orders Esben Haabendal
2026-09-07 14:50 ` [PATCH v8 4/9] iio: accel: mma8452: Only apply trigger type when not set by firmware Esben Haabendal
2026-09-07 14:51 ` [PATCH v8 5/9] iio: accel: mma8452: Fix unintended comment indent Esben Haabendal
2026-09-07 15:04 ` Joshua Crofts
2026-09-07 14:51 ` [PATCH v8 6/9] iio: accel: mma8452: Add comment block for struct mma8452_data Esben Haabendal
2026-09-07 15:14 ` Joshua Crofts
2026-09-07 16:28 ` Esben Haabendal
2026-09-08 10:36 ` Andy Shevchenko
2026-09-13 23:15 ` Jonathan Cameron
2026-09-14 6:50 ` Esben Haabendal
2026-09-07 14:51 ` [PATCH v8 7/9] iio: accel: mma8452: Allow open drain interrupt pin configuration Esben Haabendal
2026-09-07 14:51 ` [PATCH v8 8/9] iio: accel: mma8452: Use proper error code when missing device model Esben Haabendal
2026-09-07 14:51 ` [PATCH v8 9/9] iio: accel: mma8452: Support interrupt sharing Esben Haabendal
2026-09-07 15:10 ` Joshua Crofts
2026-09-07 16:36 ` Esben Haabendal
2026-09-09 9:21 ` Joshua Crofts
2026-09-13 23:22 ` Jonathan Cameron
2026-09-14 7:15 ` Esben Haabendal [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87y0d4pal0.fsf@geanix.com \
--to=esben@geanix.com \
--cc=andy@kernel.org \
--cc=christoph.muellner@theobroma-systems.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dlechner@baylibre.com \
--cc=jic23@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=lars@metafoo.de \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=martin.kepplinger@theobroma-systems.com \
--cc=martink@posteo.de \
--cc=nuno.sa@analog.com \
--cc=robh@kernel.org \
--cc=sean@geanix.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®