Apologies for the resend adding Andy and Jarkko.
This series attempts to align as much IRQ handling into the
probe path as possible. Note that I don't have a great setup
for testing these patches so they are mostly just build tested
and need careful review and testing before any of them are
merged.
The series brings the ACPI path inline with the way the device
tree path handles the IRQ entirely at probe time. However,
it still leaves any IRQ specified through the board_info as
being handled at device time. In that case we need to cache
something from the board_info until probe time, which leaves
any alternative solution with something basically the same as
the current handling although perhaps caching more stuff.
Thanks,
Charles
See previous discussions:
- https://lkml.org/lkml/2019/2/15/989
- https://www.spinics.net/lists/linux-i2c/msg39541.html
Charles Keepax (5):
i2c: acpi: Factor out getting the IRQ from ACPI
i2c: acpi: Use available IRQ helper functions
i2c: core: Move ACPI IRQ handling to probe time
i2c: core: Move ACPI gpio IRQ handling into i2c_acpi_get_irq
i2c: core: Tidy up handling of init_irq
drivers/i2c/i2c-core-acpi.c | 50 ++++++++++++++++++++++++++++++---------------
drivers/i2c/i2c-core-base.c | 11 +++++-----
drivers/i2c/i2c-core.h | 9 ++++++++
3 files changed, 48 insertions(+), 22 deletions(-)
--
2.11.0
It makes sense to contain all the ACPI IRQ handling in a single helper
function.
Signed-off-by: Charles Keepax <[email protected]>
---
Note that this one is somewhat interesting, it seems the search
through the resource list is done against the companion device
of the adapter but the GPIO search is done against the companion
device of the client. It feels to me like these really should
be done on the same device, and certainly this is what SPI
does (both against the equivalent of the adapter). Perhaps
someone with more ACPI knowledge than myself could comment?
Thanks,
Charles
drivers/i2c/i2c-core-acpi.c | 3 +++
drivers/i2c/i2c-core-base.c | 4 ----
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
index e332760bf9ebc..0c882d956e9a4 100644
--- a/drivers/i2c/i2c-core-acpi.c
+++ b/drivers/i2c/i2c-core-acpi.c
@@ -164,6 +164,9 @@ int i2c_acpi_get_irq(struct i2c_client *client, int *irq)
acpi_dev_free_resource_list(&resource_list);
+ if (*irq < 0)
+ *irq = acpi_dev_gpio_irq_get(ACPI_COMPANION(&client->dev), 0);
+
return 0;
}
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index c1afa17a76bfc..f958b50c78c04 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -336,10 +336,6 @@ static int i2c_device_probe(struct device *dev)
irq = of_irq_get(dev->of_node, 0);
} else if (ACPI_COMPANION(dev)) {
i2c_acpi_get_irq(client, &irq);
-
- if (irq == -ENOENT)
- irq = acpi_dev_gpio_irq_get(ACPI_COMPANION(dev),
- 0);
}
if (irq == -EPROBE_DEFER)
return irq;
--
2.11.0
Only set init_irq during i2c_device_new and only handle client->irq on
the probe/remove paths.
Suggested-by: Benjamin Tissoires <[email protected]>
Signed-off-by: Charles Keepax <[email protected]>
---
drivers/i2c/i2c-core-base.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index f958b50c78c04..c0a52802d23e7 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -322,6 +322,8 @@ static int i2c_device_probe(struct device *dev)
driver = to_i2c_driver(dev->driver);
+ client->irq = client->init_irq;
+
if (!client->irq && !driver->disable_i2c_core_irq_mapping) {
int irq = -ENOENT;
@@ -432,7 +434,7 @@ static int i2c_device_remove(struct device *dev)
dev_pm_clear_wake_irq(&client->dev);
device_init_wakeup(&client->dev, false);
- client->irq = client->init_irq;
+ client->irq = 0;
if (client->flags & I2C_CLIENT_HOST_NOTIFY)
pm_runtime_put(&client->adapter->dev);
@@ -749,7 +751,6 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf
if (!client->init_irq)
client->init_irq = i2c_dev_irq_from_resources(info->resources,
info->num_resources);
- client->irq = client->init_irq;
strlcpy(client->name, info->type, sizeof(client->name));
--
2.11.0
On Tue, May 21, 2019 at 04:05:01PM +0100, Charles Keepax wrote:
> It makes sense to contain all the ACPI IRQ handling in a single helper
> function.
> Note that this one is somewhat interesting, it seems the search
> through the resource list is done against the companion device
> of the adapter but the GPIO search is done against the companion
> device of the client. It feels to me like these really should
> be done on the same device, and certainly this is what SPI
> does (both against the equivalent of the adapter). Perhaps
> someone with more ACPI knowledge than myself could comment?
It would be interesting to see the path how you come to this conclusion.
> acpi_dev_free_resource_list(&resource_list);
>
> + if (*irq < 0)
> + *irq = acpi_dev_gpio_irq_get(ACPI_COMPANION(&client->dev), 0);
I think adev here is what we may use here.
You may put assert here and see if it happens when you test your series.
--
With Best Regards,
Andy Shevchenko
On Tue, May 21, 2019 at 08:27:26PM +0300, Andy Shevchenko wrote:
> On Tue, May 21, 2019 at 04:05:01PM +0100, Charles Keepax wrote:
> > It makes sense to contain all the ACPI IRQ handling in a single helper
> > function.
>
> > Note that this one is somewhat interesting, it seems the search
> > through the resource list is done against the companion device
> > of the adapter but the GPIO search is done against the companion
> > device of the client. It feels to me like these really should
> > be done on the same device, and certainly this is what SPI
> > does (both against the equivalent of the adapter). Perhaps
> > someone with more ACPI knowledge than myself could comment?
>
> It would be interesting to see the path how you come to this conclusion.
>
Apologies but I am not sure which conclusion you are referencing.
Assuming it is them being called with different acpi_device's.
It is perhaps me misunderstanding things but it looks like
i2c_acpi_get_info implies the adev should correspond to the
adapter. Where as acpi_dev_gpio_irq_get is called with the result
of ACPI_COMPANION(dev) where dev is client->dev.
> > acpi_dev_free_resource_list(&resource_list);
> >
> > + if (*irq < 0)
> > + *irq = acpi_dev_gpio_irq_get(ACPI_COMPANION(&client->dev), 0);
>
> I think adev here is what we may use here.
>
Indeed that is what I would have expected as well, I will update
the code to do so and hopefully any issues will come out in
testing.
> You may put assert here and see if it happens when you test your series.
>
Alas I don't have a good way to test this series, they come out
of some additional work Wolfram wanted based on some issues
caused by a device tree fix I made a while back.
Thanks,
Charles