Skip to content

Commit 7f26120

Browse files
jwrdegoederafaeljw
authored andcommitted
ACPI: x86: Make UART skip quirks work on PCI UARTs without an UID
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@redhat.com> Link: https://patch.msgid.link/20241109215936.83004-1-hdegoede@redhat.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 2d5404c commit 7f26120

File tree

1 file changed

+39
-8
lines changed

1 file changed

+39
-8
lines changed

drivers/acpi/x86/utils.c

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include <linux/acpi.h>
1414
#include <linux/dmi.h>
15+
#include <linux/pci.h>
1516
#include <linux/platform_device.h>
1617
#include <asm/cpu_device_id.h>
1718
#include <asm/intel-family.h>
@@ -391,6 +392,19 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
391392
.driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
392393
ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
393394
},
395+
{
396+
/* Vexia Edu Atla 10 tablet 9V version */
397+
.matches = {
398+
DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
399+
DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
400+
/* Above strings are too generic, also match on BIOS date */
401+
DMI_MATCH(DMI_BIOS_DATE, "08/25/2014"),
402+
},
403+
.driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
404+
ACPI_QUIRK_UART1_SKIP |
405+
ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY |
406+
ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS),
407+
},
394408
{
395409
/* Whitelabel (sold as various brands) TM800A550L */
396410
.matches = {
@@ -439,18 +453,35 @@ static int acpi_dmi_skip_serdev_enumeration(struct device *controller_parent, bo
439453
struct acpi_device *adev = ACPI_COMPANION(controller_parent);
440454
const struct dmi_system_id *dmi_id;
441455
long quirks = 0;
442-
u64 uid;
443-
int ret;
456+
u64 uid = 0;
444457

445-
ret = acpi_dev_uid_to_integer(adev, &uid);
446-
if (ret)
458+
dmi_id = dmi_first_match(acpi_quirk_skip_dmi_ids);
459+
if (!dmi_id)
447460
return 0;
448461

449-
dmi_id = dmi_first_match(acpi_quirk_skip_dmi_ids);
450-
if (dmi_id)
451-
quirks = (unsigned long)dmi_id->driver_data;
462+
quirks = (unsigned long)dmi_id->driver_data;
463+
464+
/* uid is left at 0 on errors and 0 is not a valid UART UID */
465+
acpi_dev_uid_to_integer(adev, &uid);
466+
467+
/* For PCI UARTs without an UID */
468+
if (!uid && dev_is_pci(controller_parent)) {
469+
struct pci_dev *pdev = to_pci_dev(controller_parent);
470+
471+
/*
472+
* Devfn values for PCI UARTs on Bay Trail SoCs, which are
473+
* the only devices where this fallback is necessary.
474+
*/
475+
if (pdev->devfn == PCI_DEVFN(0x1e, 3))
476+
uid = 1;
477+
else if (pdev->devfn == PCI_DEVFN(0x1e, 4))
478+
uid = 2;
479+
}
480+
481+
if (!uid)
482+
return 0;
452483

453-
if (!dev_is_platform(controller_parent)) {
484+
if (!dev_is_platform(controller_parent) && !dev_is_pci(controller_parent)) {
454485
/* PNP enumerated UARTs */
455486
if ((quirks & ACPI_QUIRK_PNP_UART1_SKIP) && uid == 1)
456487
*skip = true;

0 commit comments

Comments
 (0)