Re: [PATCH] ACPI: x86: Make UART skip quirks work on PCI UARTs without an UID

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, Nov 9, 2024 at 10:59 PM Hans de Goede <hdegoede@xxxxxxxxxx> wrote:
>
> The Vexia EDU ATLA 10 tablet (9V version) which shipped with Android 4.2
> as factory OS has the usual broken DSDT issues for x86 Android tablets.
>
> On top of that this tablet is special because all its LPSS island
> peripherals are enumerated as PCI devices rather then as ACPI devices as
> they typically are.
>
> For the x86-android-tablets kmod to be able to instantiate a serdev client
> for the Bluetooth HCI on this tablet, an ACPI_QUIRK_UART1_SKIP quirk is
> necessary.
>
> Modify acpi_dmi_skip_serdev_enumeration() to work with PCI enumerated
> UARTs without an UID, such as the UARTs on this tablet.
>
> Also make acpi_dmi_skip_serdev_enumeration() exit early if there are no
> quirks, since there is nothing to do then.
>
> And add the necessary quirks for the Vexia EDU ATLA 10 tablet.
>
> This should compile with CONFIG_PCI being unset without issues because
> dev_is_pci() is defined as "(false)" then.
>
> Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx>
> ---
>  drivers/acpi/x86/utils.c | 49 ++++++++++++++++++++++++++++++++--------
>  1 file changed, 40 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c
> index 6af546b21574..3eec889d4f5f 100644
> --- a/drivers/acpi/x86/utils.c
> +++ b/drivers/acpi/x86/utils.c
> @@ -12,6 +12,7 @@
>
>  #include <linux/acpi.h>
>  #include <linux/dmi.h>
> +#include <linux/pci.h>
>  #include <linux/platform_device.h>
>  #include <asm/cpu_device_id.h>
>  #include <asm/intel-family.h>
> @@ -391,6 +392,19 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
>                 .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
>                                         ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
>         },
> +       {
> +               /* Vexia Edu Atla 10 tablet 9V version */
> +               .matches = {
> +                       DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
> +                       DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
> +                       /* Above strings are too generic, also match on BIOS date */
> +                       DMI_MATCH(DMI_BIOS_DATE, "08/25/2014"),
> +               },
> +               .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
> +                                       ACPI_QUIRK_UART1_SKIP |
> +                                       ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY |
> +                                       ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS),
> +       },
>         {
>                 /* Whitelabel (sold as various brands) TM800A550L */
>                 .matches = {
> @@ -439,18 +453,35 @@ static int acpi_dmi_skip_serdev_enumeration(struct device *controller_parent, bo
>         struct acpi_device *adev = ACPI_COMPANION(controller_parent);
>         const struct dmi_system_id *dmi_id;
>         long quirks = 0;
> -       u64 uid;
> -       int ret;
> -
> -       ret = acpi_dev_uid_to_integer(adev, &uid);
> -       if (ret)
> -               return 0;
> +       u64 uid = 0;
>
>         dmi_id = dmi_first_match(acpi_quirk_skip_dmi_ids);
> -       if (dmi_id)
> -               quirks = (unsigned long)dmi_id->driver_data;
> +       if (!dmi_id)
> +               return 0;
>
> -       if (!dev_is_platform(controller_parent)) {
> +       quirks = (unsigned long)dmi_id->driver_data;
> +
> +       /* uid is left at 0 on errors and 0 is not a valid UART UID */
> +       acpi_dev_uid_to_integer(adev, &uid);
> +
> +       /* For PCI UARTs without an UID */
> +       if (!uid && dev_is_pci(controller_parent)) {
> +               struct pci_dev *pdev = to_pci_dev(controller_parent);
> +
> +               /*
> +                * Devfn values for PCI UARTs on Bay Trail SoCs, which are
> +                * the only devices where this fallback is necessary.
> +                */
> +               if (pdev->devfn == PCI_DEVFN(0x1e, 3))
> +                       uid = 1;
> +               else if (pdev->devfn == PCI_DEVFN(0x1e, 4))
> +                       uid = 2;
> +       }
> +
> +       if (!uid)
> +               return 0;
> +
> +       if (!dev_is_platform(controller_parent) && !dev_is_pci(controller_parent)) {
>                 /* PNP enumerated UARTs */
>                 if ((quirks & ACPI_QUIRK_PNP_UART1_SKIP) && uid == 1)
>                         *skip = true;
> --

Applied as 6.13 material, thanks!





[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]
  Powered by Linux