diff mbox series

[2/5] platform/x86: x86-android-tablets: Fix EBUSY error when requesting IOAPIC IRQs

Message ID 20220223133153.730337-3-hdegoede@redhat.com
State New
Headers show
Series pinctrl/baytrail platform/x86: SUS6 mux / Lenovo Yoga Tablet 2 support | expand

Commit Message

Hans de Goede Feb. 23, 2022, 1:31 p.m. UTC
Sometimes IRQs used by GPIOs in direct-IRQ mode are already registered
because they are used as ACPI "Interrupt () {}" resource for one of the
many bogus I2C devices present in the broken DSDTs of Android x86 tablets.

This is an issue if the existing (bogus) ACPI resource uses different
trigger settings then what is being requested, leading to an -EBUSY
error return of acpi_register_gsi().

Fix this by calling acpi_unregister_gsi() first, so that
the acpi_register_gsi() is allowed to change the trigger settings.

In cases where the GSI has not been registered yet
the acpi_unregister_gsi() is a no-op.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/platform/x86/x86-android-tablets.c | 6 ++++++
 1 file changed, 6 insertions(+)

Comments

Andy Shevchenko Feb. 23, 2022, 2:56 p.m. UTC | #1
On Wed, Feb 23, 2022 at 02:31:50PM +0100, Hans de Goede wrote:
> Sometimes IRQs used by GPIOs in direct-IRQ mode are already registered
> because they are used as ACPI "Interrupt () {}" resource for one of the
> many bogus I2C devices present in the broken DSDTs of Android x86 tablets.
> 
> This is an issue if the existing (bogus) ACPI resource uses different
> trigger settings then what is being requested, leading to an -EBUSY
> error return of acpi_register_gsi().
> 
> Fix this by calling acpi_unregister_gsi() first, so that
> the acpi_register_gsi() is allowed to change the trigger settings.
> 
> In cases where the GSI has not been registered yet
> the acpi_unregister_gsi() is a no-op.

...

>  	case X86_ACPI_IRQ_TYPE_APIC:
> +		/*
> +		 * The DSDT may already reference the GSI in a device skipped by
> +		 * acpi_quirk_skip_i2c_client_enumeration(). Unregister the GSI
> +		 * to avoid EBUSY errors in this case.
> +		 */
> +		acpi_unregister_gsi(data->index);

Perhaps a warning (or at least debug) message?
Hans de Goede Feb. 23, 2022, 3:16 p.m. UTC | #2
Hi,

On 2/23/22 15:56, Andy Shevchenko wrote:
> On Wed, Feb 23, 2022 at 02:31:50PM +0100, Hans de Goede wrote:
>> Sometimes IRQs used by GPIOs in direct-IRQ mode are already registered
>> because they are used as ACPI "Interrupt () {}" resource for one of the
>> many bogus I2C devices present in the broken DSDTs of Android x86 tablets.
>>
>> This is an issue if the existing (bogus) ACPI resource uses different
>> trigger settings then what is being requested, leading to an -EBUSY
>> error return of acpi_register_gsi().
>>
>> Fix this by calling acpi_unregister_gsi() first, so that
>> the acpi_register_gsi() is allowed to change the trigger settings.
>>
>> In cases where the GSI has not been registered yet
>> the acpi_unregister_gsi() is a no-op.
> 
> ...
> 
>>  	case X86_ACPI_IRQ_TYPE_APIC:
>> +		/*
>> +		 * The DSDT may already reference the GSI in a device skipped by
>> +		 * acpi_quirk_skip_i2c_client_enumeration(). Unregister the GSI
>> +		 * to avoid EBUSY errors in this case.
>> +		 */
>> +		acpi_unregister_gsi(data->index);
> 
> Perhaps a warning (or at least debug) message?

The function returns void, so we cannot check if it did anything or not.

Regards,

Hans
Andy Shevchenko Feb. 23, 2022, 3:38 p.m. UTC | #3
On Wed, Feb 23, 2022 at 04:16:42PM +0100, Hans de Goede wrote:
> On 2/23/22 15:56, Andy Shevchenko wrote:
> > On Wed, Feb 23, 2022 at 02:31:50PM +0100, Hans de Goede wrote:

...

> >>  	case X86_ACPI_IRQ_TYPE_APIC:
> >> +		/*
> >> +		 * The DSDT may already reference the GSI in a device skipped by
> >> +		 * acpi_quirk_skip_i2c_client_enumeration(). Unregister the GSI
> >> +		 * to avoid EBUSY errors in this case.
> >> +		 */
> >> +		acpi_unregister_gsi(data->index);
> > 
> > Perhaps a warning (or at least debug) message?
> 
> The function returns void, so we cannot check if it did anything or not.

Another approach may be to try to register GSI and if fail, try unregister
and register again?
Hans de Goede Feb. 24, 2022, 4:49 p.m. UTC | #4
Hi,

On 2/23/22 16:38, Andy Shevchenko wrote:
> On Wed, Feb 23, 2022 at 04:16:42PM +0100, Hans de Goede wrote:
>> On 2/23/22 15:56, Andy Shevchenko wrote:
>>> On Wed, Feb 23, 2022 at 02:31:50PM +0100, Hans de Goede wrote:
> 
> ...
> 
>>>>  	case X86_ACPI_IRQ_TYPE_APIC:
>>>> +		/*
>>>> +		 * The DSDT may already reference the GSI in a device skipped by
>>>> +		 * acpi_quirk_skip_i2c_client_enumeration(). Unregister the GSI
>>>> +		 * to avoid EBUSY errors in this case.
>>>> +		 */
>>>> +		acpi_unregister_gsi(data->index);
>>>
>>> Perhaps a warning (or at least debug) message?
>>
>> The function returns void, so we cannot check if it did anything or not.
> 
> Another approach may be to try to register GSI and if fail, try unregister
> and register again?

Since we only run this on boards where it is specifically enabled and it
thus has been tested to be safe I believe that that needlessly complicates
things, so I'm just going to merge this as is.

Regards,

Hans
diff mbox series

Patch

diff --git a/drivers/platform/x86/x86-android-tablets.c b/drivers/platform/x86/x86-android-tablets.c
index f280c82d5ba5..61e526e048c3 100644
--- a/drivers/platform/x86/x86-android-tablets.c
+++ b/drivers/platform/x86/x86-android-tablets.c
@@ -89,6 +89,12 @@  static int x86_acpi_irq_helper_get(const struct x86_acpi_irq_data *data)
 
 	switch (data->type) {
 	case X86_ACPI_IRQ_TYPE_APIC:
+		/*
+		 * The DSDT may already reference the GSI in a device skipped by
+		 * acpi_quirk_skip_i2c_client_enumeration(). Unregister the GSI
+		 * to avoid EBUSY errors in this case.
+		 */
+		acpi_unregister_gsi(data->index);
 		irq = acpi_register_gsi(NULL, data->index, data->trigger, data->polarity);
 		if (irq < 0)
 			pr_err("error %d getting APIC IRQ %d\n", irq, data->index);