From 981fd70a5ac4347368fa8a3329b7d67f1c567ee7 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 4 Dec 2024 21:42:12 +0100 Subject: [PATCH 01/16] platform/x86: x86-android-tablets: Add missing __init to get_i2c_adap_by_*() MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit get_i2c_adap_by_handle() and get_i2c_adap_by_pci_parent() both are only used by x86_instantiate_i2c_client() which is __init itself and in case of the latter it also uses match_parent() which is also __init. Fixes: 5b78e809f948 ("platform/x86: x86-android-tablets: Add support for getting i2c_adapter by PCI parent devname()") Reviewed-by: Andy Shevchenko Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20241204204227.95757-2-hdegoede@redhat.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/x86-android-tablets/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c index 4218afcec0e9..40b5cd9b172f 100644 --- a/drivers/platform/x86/x86-android-tablets/core.c +++ b/drivers/platform/x86/x86-android-tablets/core.c @@ -157,7 +157,7 @@ static struct gpiod_lookup_table * const *gpiod_lookup_tables; static const struct software_node *bat_swnode; static void (*exit_handler)(void); -static struct i2c_adapter * +static __init struct i2c_adapter * get_i2c_adap_by_handle(const struct x86_i2c_client_info *client_info) { acpi_handle handle; @@ -177,7 +177,7 @@ static __init int match_parent(struct device *dev, const void *data) return dev->parent == data; } -static struct i2c_adapter * +static __init struct i2c_adapter * get_i2c_adap_by_pci_parent(const struct x86_i2c_client_info *client_info) { struct i2c_adapter *adap = NULL; -- 2.51.0 From f6728073baa172be6223512fffd72796de891536 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 4 Dec 2024 21:42:13 +0100 Subject: [PATCH 02/16] platform/x86: x86-android-tablets: Make variables only used locally static MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Commit 06f876def346 ("platform/x86: x86-android-tablets: Add support for Vexia EDU ATLA 10 tablet") omitted the static keyword from some variables which are only used inside other.c . Add the missing static keyword to these, this fixes the following warnings: .../x86-android-tablets/other.c:605:12: sparse: sparse: symbol 'crystal_cove_pwrsrc_psy' was not declared. Should it be static? .../x86-android-tablets/other.c:612:28: sparse: sparse: symbol 'vexia_edu_atla10_ulpmc_node' was not declared. Should it be static? Fixes: 06f876def346 ("platform/x86: x86-android-tablets: Add support for Vexia EDU ATLA 10 tablet") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202411301001.1glTy7Xm-lkp@intel.com/ Signed-off-by: Hans de Goede Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20241204204227.95757-3-hdegoede@redhat.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/x86-android-tablets/other.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/x86-android-tablets/other.c b/drivers/platform/x86/x86-android-tablets/other.c index 735df818f76b..3cd0db74c6c9 100644 --- a/drivers/platform/x86/x86-android-tablets/other.c +++ b/drivers/platform/x86/x86-android-tablets/other.c @@ -602,14 +602,14 @@ const struct x86_dev_info whitelabel_tm800a550l_info __initconst = { * Vexia EDU ATLA 10 tablet, Android 4.2 / 4.4 + Guadalinex Ubuntu tablet * distributed to schools in the Spanish Andalucía region. */ -const char * const crystal_cove_pwrsrc_psy[] = { "crystal_cove_pwrsrc" }; +static const char * const crystal_cove_pwrsrc_psy[] = { "crystal_cove_pwrsrc" }; static const struct property_entry vexia_edu_atla10_ulpmc_props[] = { PROPERTY_ENTRY_STRING_ARRAY("supplied-from", crystal_cove_pwrsrc_psy), { } }; -const struct software_node vexia_edu_atla10_ulpmc_node = { +static const struct software_node vexia_edu_atla10_ulpmc_node = { .properties = vexia_edu_atla10_ulpmc_props, }; -- 2.51.0 From 478b00a623d6c8ae23a1be7bcc96cb5497045cef Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 4 Dec 2024 21:42:14 +0100 Subject: [PATCH 03/16] platform/x86: serdev_helpers: Check for serial_ctrl_uid == NULL MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit dell_uart_bl_pdev_probe() calls get_serdev_controller() with the serial_ctrl_uid parameter set to NULL. In case of errors this NULL parameter then gets passed to pr_err() as argument matching a "%s" conversion specification. This leads to compiler warnings when building with "make W=1". Check serial_ctrl_uid before passing it to pr_err() to avoid these. Fixes: dc5afd720f84 ("platform/x86: Add new get_serdev_controller() helper") Cc: stable@vger.kernel.org Suggested-by: Ilpo Järvinen Signed-off-by: Hans de Goede Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20241204204227.95757-4-hdegoede@redhat.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/serdev_helpers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/serdev_helpers.h b/drivers/platform/x86/serdev_helpers.h index bcf3a0c356ea..3bc7fd8e1e19 100644 --- a/drivers/platform/x86/serdev_helpers.h +++ b/drivers/platform/x86/serdev_helpers.h @@ -35,7 +35,7 @@ get_serdev_controller(const char *serial_ctrl_hid, ctrl_adev = acpi_dev_get_first_match_dev(serial_ctrl_hid, serial_ctrl_uid, -1); if (!ctrl_adev) { pr_err("error could not get %s/%s serial-ctrl adev\n", - serial_ctrl_hid, serial_ctrl_uid); + serial_ctrl_hid, serial_ctrl_uid ?: "*"); return ERR_PTR(-ENODEV); } @@ -43,7 +43,7 @@ get_serdev_controller(const char *serial_ctrl_hid, ctrl_dev = get_device(acpi_get_first_physical_node(ctrl_adev)); if (!ctrl_dev) { pr_err("error could not get %s/%s serial-ctrl physical node\n", - serial_ctrl_hid, serial_ctrl_uid); + serial_ctrl_hid, serial_ctrl_uid ?: "*"); ctrl_dev = ERR_PTR(-ENODEV); goto put_ctrl_adev; } -- 2.51.0 From a6593c5c50455852cd3b2b51e09bdec90b99738f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 4 Dec 2024 21:42:15 +0100 Subject: [PATCH 04/16] platform/x86: serdev_helpers: Add get_serdev_controller_from_parent() helper MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The x86-android-tablets code needs to be able to get a serdev_controller device from a PCI parent, rather then by the ACPI HID+UID of the parent, because on some tablets the UARTs are enumerated as PCI devices instead of ACPI devices. Split the code to walk the device hierarchy to find the serdev_controller from its parents out into a get_serdev_controller_from_parent() helper so that the x86-android-tablets code can re-use it. Reviewed-by: Andy Shevchenko Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20241204204227.95757-5-hdegoede@redhat.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/serdev_helpers.h | 60 +++++++++++++++------------ 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/drivers/platform/x86/serdev_helpers.h b/drivers/platform/x86/serdev_helpers.h index 3bc7fd8e1e19..57eac75805e2 100644 --- a/drivers/platform/x86/serdev_helpers.h +++ b/drivers/platform/x86/serdev_helpers.h @@ -22,32 +22,14 @@ #include static inline struct device * -get_serdev_controller(const char *serial_ctrl_hid, - const char *serial_ctrl_uid, - int serial_ctrl_port, - const char *serdev_ctrl_name) +get_serdev_controller_from_parent(struct device *ctrl_dev, + int serial_ctrl_port, + const char *serdev_ctrl_name) { - struct device *ctrl_dev, *child; - struct acpi_device *ctrl_adev; + struct device *child; char name[32]; int i; - ctrl_adev = acpi_dev_get_first_match_dev(serial_ctrl_hid, serial_ctrl_uid, -1); - if (!ctrl_adev) { - pr_err("error could not get %s/%s serial-ctrl adev\n", - serial_ctrl_hid, serial_ctrl_uid ?: "*"); - return ERR_PTR(-ENODEV); - } - - /* get_first_physical_node() returns a weak ref */ - ctrl_dev = get_device(acpi_get_first_physical_node(ctrl_adev)); - if (!ctrl_dev) { - pr_err("error could not get %s/%s serial-ctrl physical node\n", - serial_ctrl_hid, serial_ctrl_uid ?: "*"); - ctrl_dev = ERR_PTR(-ENODEV); - goto put_ctrl_adev; - } - /* Walk host -> uart-ctrl -> port -> serdev-ctrl */ for (i = 0; i < 3; i++) { switch (i) { @@ -67,14 +49,40 @@ get_serdev_controller(const char *serial_ctrl_hid, put_device(ctrl_dev); if (!child) { pr_err("error could not find '%s' device\n", name); - ctrl_dev = ERR_PTR(-ENODEV); - goto put_ctrl_adev; + return ERR_PTR(-ENODEV); } ctrl_dev = child; } -put_ctrl_adev: - acpi_dev_put(ctrl_adev); return ctrl_dev; } + +static inline struct device * +get_serdev_controller(const char *serial_ctrl_hid, + const char *serial_ctrl_uid, + int serial_ctrl_port, + const char *serdev_ctrl_name) +{ + struct acpi_device *adev; + struct device *parent; + + adev = acpi_dev_get_first_match_dev(serial_ctrl_hid, serial_ctrl_uid, -1); + if (!adev) { + pr_err("error could not get %s/%s serial-ctrl adev\n", + serial_ctrl_hid, serial_ctrl_uid ?: "*"); + return ERR_PTR(-ENODEV); + } + + /* get_first_physical_node() returns a weak ref */ + parent = get_device(acpi_get_first_physical_node(adev)); + acpi_dev_put(adev); + if (!parent) { + pr_err("error could not get %s/%s serial-ctrl physical node\n", + serial_ctrl_hid, serial_ctrl_uid ?: "*"); + return ERR_PTR(-ENODEV); + } + + /* This puts our reference on parent and returns a ref on the ctrl */ + return get_serdev_controller_from_parent(parent, serial_ctrl_port, serdev_ctrl_name); +} -- 2.51.0 From c1007dd139b6f8b2b00ba7bdce32a94c3da34dbe Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 4 Dec 2024 21:42:16 +0100 Subject: [PATCH 05/16] platform/x86: x86-android-tablets: Change x86_instantiate_serdev() prototype MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Make x86_instantiate_serdev() take a "struct x86_dev_info *" + idx as arguments instead of a "struct x86_serdev_info *" + idx. This makes the x86_instantiate_serdev() prototype match the x86_instantiate_i2c_client() and x86_instantiate_spi_dev() prototypes. Reviewed-by: Andy Shevchenko Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20241204204227.95757-6-hdegoede@redhat.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/x86-android-tablets/core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c index 40b5cd9b172f..3f5c83f4d0e1 100644 --- a/drivers/platform/x86/x86-android-tablets/core.c +++ b/drivers/platform/x86/x86-android-tablets/core.c @@ -271,8 +271,9 @@ static __init int x86_instantiate_spi_dev(const struct x86_dev_info *dev_info, i return 0; } -static __init int x86_instantiate_serdev(const struct x86_serdev_info *info, int idx) +static __init int x86_instantiate_serdev(const struct x86_dev_info *dev_info, int idx) { + const struct x86_serdev_info *info = &dev_info->serdev_info[idx]; struct acpi_device *serdev_adev; struct serdev_device *serdev; struct device *ctrl_dev; @@ -446,7 +447,7 @@ static __init int x86_android_tablet_probe(struct platform_device *pdev) serdev_count = dev_info->serdev_count; for (i = 0; i < serdev_count; i++) { - ret = x86_instantiate_serdev(&dev_info->serdev_info[i], i); + ret = x86_instantiate_serdev(dev_info, i); if (ret < 0) { x86_android_tablet_remove(pdev); return ret; -- 2.51.0 From dd6db239cb30ef1ccc0084a530839c9897009a6f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 4 Dec 2024 21:42:17 +0100 Subject: [PATCH 06/16] platform/x86: x86-android-tablets: Store serdev-controller ACPI HID + UID in a union MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Store the serdev-controller ACPI HID + UID in a union inside struct x86_serdev_info. This is a preparation patch for adding support for PCI enumerated serdev- controllers which will be done by the devfn value of the PCI device. Reviewed-by: Andy Shevchenko Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20241204204227.95757-7-hdegoede@redhat.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/x86-android-tablets/asus.c | 4 ++-- drivers/platform/x86/x86-android-tablets/core.c | 2 +- drivers/platform/x86/x86-android-tablets/lenovo.c | 4 ++-- .../x86/x86-android-tablets/x86-android-tablets.h | 8 ++++++-- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/platform/x86/x86-android-tablets/asus.c b/drivers/platform/x86/x86-android-tablets/asus.c index 07fbeab2319a..7dde63b9943f 100644 --- a/drivers/platform/x86/x86-android-tablets/asus.c +++ b/drivers/platform/x86/x86-android-tablets/asus.c @@ -145,8 +145,8 @@ static const struct x86_i2c_client_info asus_me176c_i2c_clients[] __initconst = static const struct x86_serdev_info asus_me176c_serdevs[] __initconst = { { - .ctrl_hid = "80860F0A", - .ctrl_uid = "2", + .ctrl.acpi.hid = "80860F0A", + .ctrl.acpi.uid = "2", .ctrl_devname = "serial0", .serdev_hid = "BCM2E3A", }, diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c index 3f5c83f4d0e1..19962abba38d 100644 --- a/drivers/platform/x86/x86-android-tablets/core.c +++ b/drivers/platform/x86/x86-android-tablets/core.c @@ -279,7 +279,7 @@ static __init int x86_instantiate_serdev(const struct x86_dev_info *dev_info, in struct device *ctrl_dev; int ret = -ENODEV; - ctrl_dev = get_serdev_controller(info->ctrl_hid, info->ctrl_uid, 0, + ctrl_dev = get_serdev_controller(info->ctrl.acpi.hid, info->ctrl.acpi.uid, 0, info->ctrl_devname); if (IS_ERR(ctrl_dev)) return PTR_ERR(ctrl_dev); diff --git a/drivers/platform/x86/x86-android-tablets/lenovo.c b/drivers/platform/x86/x86-android-tablets/lenovo.c index a60efbaf4817..1241a97cda39 100644 --- a/drivers/platform/x86/x86-android-tablets/lenovo.c +++ b/drivers/platform/x86/x86-android-tablets/lenovo.c @@ -178,8 +178,8 @@ static const struct platform_device_info lenovo_yb1_x90_pdevs[] __initconst = { */ static const struct x86_serdev_info lenovo_yb1_x90_serdevs[] __initconst = { { - .ctrl_hid = "8086228A", - .ctrl_uid = "1", + .ctrl.acpi.hid = "8086228A", + .ctrl.acpi.uid = "1", .ctrl_devname = "serial0", .serdev_hid = "BCM2E1A", }, diff --git a/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h b/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h index 0fc7e8cff672..5ddec4beb552 100644 --- a/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h +++ b/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h @@ -57,8 +57,12 @@ struct x86_spi_dev_info { }; struct x86_serdev_info { - const char *ctrl_hid; - const char *ctrl_uid; + union { + struct { + const char *hid; + const char *uid; + } acpi; + } ctrl; const char *ctrl_devname; /* * ATM the serdev core only supports of or ACPI matching; and so far all -- 2.51.0 From 7d28fb4d16fb8ad2309616ee3bdcdbf161c13dc5 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 4 Dec 2024 21:42:18 +0100 Subject: [PATCH 07/16] platform/x86: x86-android-tablets: Add support for getting serdev-controller by PCI parent MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit On the Vexia EDU ATLA 10 tablet, which ships with Android + a custom Linux (guadalinex) using the custom Android kernel the UART controllers are not enumerated as ACPI devices as they typically are. Instead they are enumerated through PCI and getting the serdev-controller by ACPI HID + UID does not work. Add support for getting the serdev-controller by the PCI devfn of its parent instead. This also renames the use_pci_devname flag to use_pci since the former name now no longer is accurate. Reviewed-by: Andy Shevchenko Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20241204204227.95757-8-hdegoede@redhat.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- .../platform/x86/x86-android-tablets/core.c | 22 ++++++++++++++++--- .../platform/x86/x86-android-tablets/other.c | 2 +- .../x86-android-tablets/x86-android-tablets.h | 5 ++++- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c index 19962abba38d..2a9c47178505 100644 --- a/drivers/platform/x86/x86-android-tablets/core.c +++ b/drivers/platform/x86/x86-android-tablets/core.c @@ -212,7 +212,7 @@ static __init int x86_instantiate_i2c_client(const struct x86_dev_info *dev_info if (board_info.irq < 0) return board_info.irq; - if (dev_info->use_pci_devname) + if (dev_info->use_pci) adap = get_i2c_adap_by_pci_parent(client_info); else adap = get_i2c_adap_by_handle(client_info); @@ -271,6 +271,19 @@ static __init int x86_instantiate_spi_dev(const struct x86_dev_info *dev_info, i return 0; } +static __init struct device * +get_serdev_controller_by_pci_parent(const struct x86_serdev_info *info) +{ + struct pci_dev *pdev; + + pdev = pci_get_domain_bus_and_slot(0, 0, info->ctrl.pci.devfn); + if (!pdev) + return ERR_PTR(-EPROBE_DEFER); + + /* This puts our reference on pdev and returns a ref on the ctrl */ + return get_serdev_controller_from_parent(&pdev->dev, 0, info->ctrl_devname); +} + static __init int x86_instantiate_serdev(const struct x86_dev_info *dev_info, int idx) { const struct x86_serdev_info *info = &dev_info->serdev_info[idx]; @@ -279,8 +292,11 @@ static __init int x86_instantiate_serdev(const struct x86_dev_info *dev_info, in struct device *ctrl_dev; int ret = -ENODEV; - ctrl_dev = get_serdev_controller(info->ctrl.acpi.hid, info->ctrl.acpi.uid, 0, - info->ctrl_devname); + if (dev_info->use_pci) + ctrl_dev = get_serdev_controller_by_pci_parent(info); + else + ctrl_dev = get_serdev_controller(info->ctrl.acpi.hid, info->ctrl.acpi.uid, + 0, info->ctrl_devname); if (IS_ERR(ctrl_dev)) return PTR_ERR(ctrl_dev); diff --git a/drivers/platform/x86/x86-android-tablets/other.c b/drivers/platform/x86/x86-android-tablets/other.c index 3cd0db74c6c9..251c0ea1ab79 100644 --- a/drivers/platform/x86/x86-android-tablets/other.c +++ b/drivers/platform/x86/x86-android-tablets/other.c @@ -757,7 +757,7 @@ const struct x86_dev_info vexia_edu_atla10_info __initconst = { .i2c_client_count = ARRAY_SIZE(vexia_edu_atla10_i2c_clients), .gpiod_lookup_tables = vexia_edu_atla10_gpios, .init = vexia_edu_atla10_init, - .use_pci_devname = true, + .use_pci = true, }; /* diff --git a/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h b/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h index 5ddec4beb552..63a38a0069ba 100644 --- a/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h +++ b/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h @@ -62,6 +62,9 @@ struct x86_serdev_info { const char *hid; const char *uid; } acpi; + struct { + unsigned int devfn; + } pci; } ctrl; const char *ctrl_devname; /* @@ -95,7 +98,7 @@ struct x86_dev_info { int gpio_button_count; int (*init)(struct device *dev); void (*exit)(void); - bool use_pci_devname; + bool use_pci; }; int x86_android_tablet_get_gpiod(const char *chip, int pin, const char *con_id, -- 2.51.0 From c0f1bfc141ea52ea039bd17537b46b705ff8a93d Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 4 Dec 2024 21:42:19 +0100 Subject: [PATCH 08/16] platform/x86: x86-android-tablets: Add Bluetooth support for Vexia EDU ATLA 10 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The UART used for the Bluetooth HCI on the Vexia EDU ATLA 10 is enumerated as a PCI device, but the ODBA7823 ACPI fwnode for the HCI expects it to use the more standard ACPI enumeration mode. So Bluetooth does not work out of the box. Add x86_serdev_info to make the x86-android-tablets manually associate the fwnode with the UART. Reviewed-by: Andy Shevchenko Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20241204204227.95757-9-hdegoede@redhat.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/x86-android-tablets/other.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/platform/x86/x86-android-tablets/other.c b/drivers/platform/x86/x86-android-tablets/other.c index 251c0ea1ab79..1d93d9edb23f 100644 --- a/drivers/platform/x86/x86-android-tablets/other.c +++ b/drivers/platform/x86/x86-android-tablets/other.c @@ -715,6 +715,14 @@ static const struct x86_i2c_client_info vexia_edu_atla10_i2c_clients[] __initcon } }; +static const struct x86_serdev_info vexia_edu_atla10_serdevs[] __initconst = { + { + .ctrl.pci.devfn = PCI_DEVFN(0x1e, 3), + .ctrl_devname = "serial0", + .serdev_hid = "OBDA8723", + }, +}; + static struct gpiod_lookup_table vexia_edu_atla10_ft5416_gpios = { .dev_id = "i2c-FTSC1000", .table = { @@ -755,6 +763,8 @@ static int __init vexia_edu_atla10_init(struct device *dev) const struct x86_dev_info vexia_edu_atla10_info __initconst = { .i2c_client_info = vexia_edu_atla10_i2c_clients, .i2c_client_count = ARRAY_SIZE(vexia_edu_atla10_i2c_clients), + .serdev_info = vexia_edu_atla10_serdevs, + .serdev_count = ARRAY_SIZE(vexia_edu_atla10_serdevs), .gpiod_lookup_tables = vexia_edu_atla10_gpios, .init = vexia_edu_atla10_init, .use_pci = true, -- 2.51.0 From 0130ec83c5535b034a96284eb9f31b3b5373d207 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 4 Dec 2024 20:34:41 +0100 Subject: [PATCH 09/16] platform/x86/intel: bytcrc_pwrsrc: Optionally register a power_supply dev MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit On some Android tablets with Crystal Cove PMIC the DSDT lacks an ACPI AC device to indicate whether a charger is plugged in or not. Add support for registering a "crystal_cove_pwrsrc" power_supply class device to indicate charger online status. This is made conditional on a "linux,register-pwrsrc-power_supply" boolean device-property to avoid registering a duplicate power_supply class device on devices where this is already handled by an ACPI AC device. Note the "linux,register-pwrsrc-power_supply" property is only used on x86/ACPI (non devicetree) devs and the devicetree-bindings maintainers have requested properties like these to not be added to the devicetree bindings, so the new property is deliberately not added to any bindings. Reviewed-by: Andy Shevchenko Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20241204193442.65374-2-hdegoede@redhat.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/intel/bytcrc_pwrsrc.c | 79 +++++++++++++++++++++- 1 file changed, 77 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/intel/bytcrc_pwrsrc.c b/drivers/platform/x86/intel/bytcrc_pwrsrc.c index 3edc2a9dab38..68ac040082df 100644 --- a/drivers/platform/x86/intel/bytcrc_pwrsrc.c +++ b/drivers/platform/x86/intel/bytcrc_pwrsrc.c @@ -8,13 +8,22 @@ * Copyright (C) 2013 Intel Corporation */ +#include +#include #include +#include #include #include #include +#include +#include #include +#define CRYSTALCOVE_PWRSRC_IRQ 0x03 #define CRYSTALCOVE_SPWRSRC_REG 0x1E +#define CRYSTALCOVE_SPWRSRC_USB BIT(0) +#define CRYSTALCOVE_SPWRSRC_DC BIT(1) +#define CRYSTALCOVE_SPWRSRC_BATTERY BIT(2) #define CRYSTALCOVE_RESETSRC0_REG 0x20 #define CRYSTALCOVE_RESETSRC1_REG 0x21 #define CRYSTALCOVE_WAKESRC_REG 0x22 @@ -22,6 +31,7 @@ struct crc_pwrsrc_data { struct regmap *regmap; struct dentry *debug_dentry; + struct power_supply *psy; unsigned int resetsrc0; unsigned int resetsrc1; unsigned int wakesrc; @@ -118,13 +128,60 @@ static int crc_pwrsrc_read_and_clear(struct crc_pwrsrc_data *data, return regmap_write(data->regmap, reg, *val); } +static irqreturn_t crc_pwrsrc_irq_handler(int irq, void *_data) +{ + struct crc_pwrsrc_data *data = _data; + unsigned int irq_mask; + + if (regmap_read(data->regmap, CRYSTALCOVE_PWRSRC_IRQ, &irq_mask)) + return IRQ_NONE; + + regmap_write(data->regmap, CRYSTALCOVE_PWRSRC_IRQ, irq_mask); + + power_supply_changed(data->psy); + return IRQ_HANDLED; +} + +static int crc_pwrsrc_psy_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct crc_pwrsrc_data *data = power_supply_get_drvdata(psy); + unsigned int pwrsrc; + int ret; + + if (psp != POWER_SUPPLY_PROP_ONLINE) + return -EINVAL; + + ret = regmap_read(data->regmap, CRYSTALCOVE_SPWRSRC_REG, &pwrsrc); + if (ret) + return ret; + + val->intval = !!(pwrsrc & (CRYSTALCOVE_SPWRSRC_USB | + CRYSTALCOVE_SPWRSRC_DC)); + return 0; +} + +static const enum power_supply_property crc_pwrsrc_psy_props[] = { + POWER_SUPPLY_PROP_ONLINE, +}; + +static const struct power_supply_desc crc_pwrsrc_psy_desc = { + .name = "crystal_cove_pwrsrc", + .type = POWER_SUPPLY_TYPE_MAINS, + .properties = crc_pwrsrc_psy_props, + .num_properties = ARRAY_SIZE(crc_pwrsrc_psy_props), + .get_property = crc_pwrsrc_psy_get_property, +}; + static int crc_pwrsrc_probe(struct platform_device *pdev) { struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent); + struct device *dev = &pdev->dev; struct crc_pwrsrc_data *data; - int ret; + int irq, ret; - data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; @@ -149,6 +206,24 @@ static int crc_pwrsrc_probe(struct platform_device *pdev) if (ret) return ret; + if (device_property_read_bool(dev->parent, "linux,register-pwrsrc-power_supply")) { + struct power_supply_config psy_cfg = { .drv_data = data }; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + data->psy = devm_power_supply_register(dev, &crc_pwrsrc_psy_desc, &psy_cfg); + if (IS_ERR(data->psy)) + return dev_err_probe(dev, PTR_ERR(data->psy), "registering power-supply\n"); + + ret = devm_request_threaded_irq(dev, irq, NULL, + crc_pwrsrc_irq_handler, + IRQF_ONESHOT, KBUILD_MODNAME, data); + if (ret) + return dev_err_probe(dev, ret, "requesting IRQ\n"); + } + data->debug_dentry = debugfs_create_dir(KBUILD_MODNAME, NULL); debugfs_create_file("pwrsrc", 0444, data->debug_dentry, data, &pwrsrc_fops); debugfs_create_file("resetsrc", 0444, data->debug_dentry, data, &resetsrc_fops); -- 2.51.0 From c78dd25138d104f94ddeab5248a5efe4504f205e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 4 Dec 2024 20:34:42 +0100 Subject: [PATCH 10/16] platform/x86: x86-android-tablets: Add Vexia EDU ATLA 10 EC battery driver MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The Vexia EDU ATLA 10 tablet has an embedded controller instead of giving the os direct access to the charger + fuel-gauge ICs as is normal on tablets designed for Android. There is ACPI Battery device in the DSDT using the EC which should work except that it expects the I2C controller to be enumerated as an ACPI device and the tablet's BIOS enumerates all LPSS devices as PCI devices (and changing the LPSS BIOS settings from PCI -> ACPI does not work). Add a power_supply class driver for the Atla 10 EC to expert battery info to userspace. This is made part of the x86-android-tablets directory and Kconfig option because the i2c_client it binds to is instantiated by the x86-android-tablets kmod. Reviewed-by: Andy Shevchenko Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20241204193442.65374-3-hdegoede@redhat.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- .../platform/x86/x86-android-tablets/Makefile | 2 +- .../x86/x86-android-tablets/vexia_atla10_ec.c | 261 ++++++++++++++++++ 2 files changed, 262 insertions(+), 1 deletion(-) create mode 100644 drivers/platform/x86/x86-android-tablets/vexia_atla10_ec.c diff --git a/drivers/platform/x86/x86-android-tablets/Makefile b/drivers/platform/x86/x86-android-tablets/Makefile index 41ece5a37137..313be30548bc 100644 --- a/drivers/platform/x86/x86-android-tablets/Makefile +++ b/drivers/platform/x86/x86-android-tablets/Makefile @@ -3,7 +3,7 @@ # X86 Android tablet support Makefile # +obj-$(CONFIG_X86_ANDROID_TABLETS) += vexia_atla10_ec.o obj-$(CONFIG_X86_ANDROID_TABLETS) += x86-android-tablets.o - x86-android-tablets-y := core.o dmi.o shared-psy-info.o \ asus.o lenovo.o other.o diff --git a/drivers/platform/x86/x86-android-tablets/vexia_atla10_ec.c b/drivers/platform/x86/x86-android-tablets/vexia_atla10_ec.c new file mode 100644 index 000000000000..5d02af1c5aaa --- /dev/null +++ b/drivers/platform/x86/x86-android-tablets/vexia_atla10_ec.c @@ -0,0 +1,261 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * power_supply class (battery) driver for the I2C attached embedded controller + * found on Vexia EDU ATLA 10 (9V version) tablets. + * + * This is based on the ACPI Battery device in the DSDT which should work + * expect that it expects the I2C controller to be enumerated as an ACPI + * device and the tablet's BIOS enumerates all LPSS devices as PCI devices + * (and changing the LPSS BIOS settings from PCI -> ACPI does not work). + * + * Copyright (c) 2024 Hans de Goede + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* State field uses ACPI Battery spec status bits */ +#define ACPI_BATTERY_STATE_DISCHARGING BIT(0) +#define ACPI_BATTERY_STATE_CHARGING BIT(1) + +#define ATLA10_EC_BATTERY_STATE_COMMAND 0x87 +#define ATLA10_EC_BATTERY_INFO_COMMAND 0x88 + +/* From broken ACPI battery device in DSDT */ +#define ATLA10_EC_VOLTAGE_MIN_DESIGN_uV 3750000 + +/* Update data every 5 seconds */ +#define UPDATE_INTERVAL_JIFFIES (5 * HZ) + +struct atla10_ec_battery_state { + u8 status; /* Using ACPI Battery spec status bits */ + u8 capacity; /* Percent */ + __le16 charge_now_mAh; + __le16 voltage_now_mV; + __le16 current_now_mA; + __le16 charge_full_mAh; + __le16 temp; /* centi degrees Celsius */ +} __packed; + +struct atla10_ec_battery_info { + __le16 charge_full_design_mAh; + __le16 voltage_now_mV; /* Should be design voltage, but is not ? */ + __le16 charge_full_design2_mAh; +} __packed; + +struct atla10_ec_data { + struct i2c_client *client; + struct power_supply *psy; + struct delayed_work work; + struct mutex update_lock; + struct atla10_ec_battery_info info; + struct atla10_ec_battery_state state; + bool valid; /* true if state is valid */ + unsigned long last_update; /* In jiffies */ +}; + +static int atla10_ec_cmd(struct atla10_ec_data *data, u8 cmd, u8 len, u8 *values) +{ + struct device *dev = &data->client->dev; + u8 buf[I2C_SMBUS_BLOCK_MAX]; + int ret; + + ret = i2c_smbus_read_block_data(data->client, cmd, buf); + if (ret != len) { + dev_err(dev, "I2C command 0x%02x error: %d\n", cmd, ret); + return -EIO; + } + + memcpy(values, buf, len); + return 0; +} + +static int atla10_ec_update(struct atla10_ec_data *data) +{ + int ret; + + if (data->valid && time_before(jiffies, data->last_update + UPDATE_INTERVAL_JIFFIES)) + return 0; + + ret = atla10_ec_cmd(data, ATLA10_EC_BATTERY_STATE_COMMAND, + sizeof(data->state), (u8 *)&data->state); + if (ret) + return ret; + + data->last_update = jiffies; + data->valid = true; + return 0; +} + +static int atla10_ec_psy_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct atla10_ec_data *data = power_supply_get_drvdata(psy); + int charge_now_mAh, charge_full_mAh, ret; + + guard(mutex)(&data->update_lock); + + ret = atla10_ec_update(data); + if (ret) + return ret; + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + if (data->state.status & ACPI_BATTERY_STATE_DISCHARGING) + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; + else if (data->state.status & ACPI_BATTERY_STATE_CHARGING) + val->intval = POWER_SUPPLY_STATUS_CHARGING; + else if (data->state.capacity == 100) + val->intval = POWER_SUPPLY_STATUS_FULL; + else + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; + break; + case POWER_SUPPLY_PROP_CAPACITY: + val->intval = data->state.capacity; + break; + case POWER_SUPPLY_PROP_CHARGE_NOW: + /* + * The EC has a bug where it reports charge-full-design as + * charge-now when the battery is full. Clamp charge-now to + * charge-full to workaround this. + */ + charge_now_mAh = le16_to_cpu(data->state.charge_now_mAh); + charge_full_mAh = le16_to_cpu(data->state.charge_full_mAh); + val->intval = min(charge_now_mAh, charge_full_mAh) * 1000; + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + val->intval = le16_to_cpu(data->state.voltage_now_mV) * 1000; + break; + case POWER_SUPPLY_PROP_CURRENT_NOW: + val->intval = le16_to_cpu(data->state.current_now_mA) * 1000; + /* + * Documentation/ABI/testing/sysfs-class-power specifies + * negative current for discharging. + */ + if (data->state.status & ACPI_BATTERY_STATE_DISCHARGING) + val->intval = -val->intval; + break; + case POWER_SUPPLY_PROP_CHARGE_FULL: + val->intval = le16_to_cpu(data->state.charge_full_mAh) * 1000; + break; + case POWER_SUPPLY_PROP_TEMP: + val->intval = le16_to_cpu(data->state.temp) / 10; + break; + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: + val->intval = le16_to_cpu(data->info.charge_full_design_mAh) * 1000; + break; + case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: + val->intval = ATLA10_EC_VOLTAGE_MIN_DESIGN_uV; + break; + case POWER_SUPPLY_PROP_PRESENT: + val->intval = 1; + break; + case POWER_SUPPLY_PROP_TECHNOLOGY: + val->intval = POWER_SUPPLY_TECHNOLOGY_LIPO; + break; + default: + return -EINVAL; + } + + return 0; +} + +static void atla10_ec_external_power_changed_work(struct work_struct *work) +{ + struct atla10_ec_data *data = container_of(work, struct atla10_ec_data, work.work); + + dev_dbg(&data->client->dev, "External power changed\n"); + data->valid = false; + power_supply_changed(data->psy); +} + +static void atla10_ec_external_power_changed(struct power_supply *psy) +{ + struct atla10_ec_data *data = power_supply_get_drvdata(psy); + + /* After charger plug in/out wait 0.5s for things to stabilize */ + mod_delayed_work(system_wq, &data->work, HZ / 2); +} + +static const enum power_supply_property atla10_ec_psy_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_CHARGE_NOW, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_CHARGE_FULL, + POWER_SUPPLY_PROP_TEMP, + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, + POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_TECHNOLOGY, +}; + +static const struct power_supply_desc atla10_ec_psy_desc = { + .name = "atla10_ec_battery", + .type = POWER_SUPPLY_TYPE_BATTERY, + .properties = atla10_ec_psy_props, + .num_properties = ARRAY_SIZE(atla10_ec_psy_props), + .get_property = atla10_ec_psy_get_property, + .external_power_changed = atla10_ec_external_power_changed, +}; + +static int atla10_ec_probe(struct i2c_client *client) +{ + struct power_supply_config psy_cfg = { }; + struct device *dev = &client->dev; + struct atla10_ec_data *data; + int ret; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + psy_cfg.drv_data = data; + data->client = client; + + ret = devm_mutex_init(dev, &data->update_lock); + if (ret) + return ret; + + ret = devm_delayed_work_autocancel(dev, &data->work, + atla10_ec_external_power_changed_work); + if (ret) + return ret; + + ret = atla10_ec_cmd(data, ATLA10_EC_BATTERY_INFO_COMMAND, + sizeof(data->info), (u8 *)&data->info); + if (ret) + return ret; + + data->psy = devm_power_supply_register(dev, &atla10_ec_psy_desc, &psy_cfg); + return PTR_ERR_OR_ZERO(data->psy); +} + +static const struct i2c_device_id atla10_ec_id_table[] = { + { "vexia_atla10_ec" }, + { } +}; +MODULE_DEVICE_TABLE(i2c, atla10_ec_id_table); + +static struct i2c_driver atla10_ec_driver = { + .driver = { + .name = "vexia_atla10_ec", + }, + .probe = atla10_ec_probe, + .id_table = atla10_ec_id_table, +}; +module_i2c_driver(atla10_ec_driver); + +MODULE_AUTHOR("Hans de Goede "); +MODULE_DESCRIPTION("Battery driver for Vexia EDU ATLA 10 tablet EC"); +MODULE_LICENSE("GPL"); -- 2.51.0 From f3479920605644e273768d316aa49119ec629acc Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 4 Dec 2024 15:38:07 +0100 Subject: [PATCH 11/16] platform/x86: intel: int0002_vgpio: Make the irqchip immutable MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Commit 6c846d026d49 ("gpio: Don't fiddle with irqchips marked as immutable") added a warning to indicate if the gpiolib is altering the internals of irqchips: gpio gpiochip4: (INT0002 Virtual GPIO): not an immutable chip, please consider fixing it! Fix this by making the irqchip in the int0002_vgpio driver immutable. Signed-off-by: Hans de Goede Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20241204143807.32966-1-hdegoede@redhat.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/intel/int0002_vgpio.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/intel/int0002_vgpio.c b/drivers/platform/x86/intel/int0002_vgpio.c index 0cc80603a8a9..3b48cd7a4075 100644 --- a/drivers/platform/x86/intel/int0002_vgpio.c +++ b/drivers/platform/x86/intel/int0002_vgpio.c @@ -83,8 +83,12 @@ static void int0002_irq_ack(struct irq_data *data) static void int0002_irq_unmask(struct irq_data *data) { + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + irq_hw_number_t hwirq = irqd_to_hwirq(data); u32 gpe_en_reg; + gpiochip_enable_irq(gc, hwirq); + gpe_en_reg = inl(GPE0A_EN_PORT); gpe_en_reg |= GPE0A_PME_B0_EN_BIT; outl(gpe_en_reg, GPE0A_EN_PORT); @@ -92,11 +96,15 @@ static void int0002_irq_unmask(struct irq_data *data) static void int0002_irq_mask(struct irq_data *data) { + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + irq_hw_number_t hwirq = irqd_to_hwirq(data); u32 gpe_en_reg; gpe_en_reg = inl(GPE0A_EN_PORT); gpe_en_reg &= ~GPE0A_PME_B0_EN_BIT; outl(gpe_en_reg, GPE0A_EN_PORT); + + gpiochip_disable_irq(gc, hwirq); } static int int0002_irq_set_wake(struct irq_data *data, unsigned int on) @@ -140,12 +148,14 @@ static bool int0002_check_wake(void *data) return (gpe_sts_reg & GPE0A_PME_B0_STS_BIT); } -static struct irq_chip int0002_irqchip = { +static const struct irq_chip int0002_irqchip = { .name = DRV_NAME, .irq_ack = int0002_irq_ack, .irq_mask = int0002_irq_mask, .irq_unmask = int0002_irq_unmask, .irq_set_wake = int0002_irq_set_wake, + .flags = IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, }; static void int0002_init_irq_valid_mask(struct gpio_chip *chip, @@ -203,7 +213,7 @@ static int int0002_probe(struct platform_device *pdev) } girq = &chip->irq; - girq->chip = &int0002_irqchip; + gpio_irq_chip_set_chip(girq, &int0002_irqchip); /* This let us handle the parent IRQ in the driver */ girq->parent_handler = NULL; girq->num_parents = 0; -- 2.51.0 From cd2fd6eab480dfc247b737cf7a3d6b009c4d0f1c Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 9 Dec 2024 23:05:19 +0100 Subject: [PATCH 12/16] platform/x86: int3472: Check for adev == NULL MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Not all devices have an ACPI companion fwnode, so adev might be NULL. This can e.g. (theoretically) happen when a user manually binds one of the int3472 drivers to another i2c/platform device through sysfs. Add a check for adev not being set and return -ENODEV in that case to avoid a possible NULL pointer deref in skl_int3472_get_acpi_buffer(). Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20241209220522.25288-1-hdegoede@redhat.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/intel/int3472/discrete.c | 3 +++ drivers/platform/x86/intel/int3472/tps68470.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c index d881b2cfcdfc..09fff213b091 100644 --- a/drivers/platform/x86/intel/int3472/discrete.c +++ b/drivers/platform/x86/intel/int3472/discrete.c @@ -336,6 +336,9 @@ static int skl_int3472_discrete_probe(struct platform_device *pdev) struct int3472_cldb cldb; int ret; + if (!adev) + return -ENODEV; + ret = skl_int3472_fill_cldb(adev, &cldb); if (ret) { dev_err(&pdev->dev, "Couldn't fill CLDB structure\n"); diff --git a/drivers/platform/x86/intel/int3472/tps68470.c b/drivers/platform/x86/intel/int3472/tps68470.c index 1e107fd49f82..81ac4c691963 100644 --- a/drivers/platform/x86/intel/int3472/tps68470.c +++ b/drivers/platform/x86/intel/int3472/tps68470.c @@ -152,6 +152,9 @@ static int skl_int3472_tps68470_probe(struct i2c_client *client) int ret; int i; + if (!adev) + return -ENODEV; + n_consumers = skl_int3472_fill_clk_pdata(&client->dev, &clk_pdata); if (n_consumers < 0) return n_consumers; -- 2.51.0 From 1dd0cb9cabf37fbe20f0a66e4c3972cb21240aed Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 9 Dec 2024 23:05:20 +0100 Subject: [PATCH 13/16] platform/x86: int3472: Make "pin number mismatch" message a debug message MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit It seems that Windows is only using the ACPI GPIO resources and never looks at the part of the _DSM return value which encodes the pin number. For example on a Terra Pad 1262 v2 the following messages are printend: int3472-discrete INT3472:01: reset \_SB.GPI0 pin number mismatch _DSM 103 resource 359 int3472-discrete INT3472:01: powerdown \_SB.GPI0 pin number mismatch _DSM 207 resource 335 int3472-discrete INT3472:02: reset \_SB.GPI0 pin number mismatch _DSM 101 resource 357 Notice for the 2 reset pins that the _DSM value is off by 256, this is caused by there only being 8 bits reserved in the _DSM return value for the pin-number. As for the powerdown pin, testing has shown that the pin-number 335 from the ACPI GPIO resource is correct and the _DSM value is bogus. Lower the warning about these mismatches to a debug message and only look at the lower 8 bits of the GPIO resource pin numbers. Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20241209220522.25288-2-hdegoede@redhat.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/intel/int3472/discrete.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c index 09fff213b091..6e2b81da2d68 100644 --- a/drivers/platform/x86/intel/int3472/discrete.c +++ b/drivers/platform/x86/intel/int3472/discrete.c @@ -220,10 +220,10 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares, int3472_get_func_and_polarity(type, &func, &polarity); pin = FIELD_GET(INT3472_GPIO_DSM_PIN, obj->integer.value); - if (pin != agpio->pin_table[0]) - dev_warn(int3472->dev, "%s %s pin number mismatch _DSM %d resource %d\n", - func, agpio->resource_source.string_ptr, pin, - agpio->pin_table[0]); + /* Pin field is not really used under Windows and wraps around at 8 bits */ + if (pin != (agpio->pin_table[0] & 0xff)) + dev_dbg(int3472->dev, FW_BUG "%s %s pin number mismatch _DSM %d resource %d\n", + func, agpio->resource_source.string_ptr, pin, agpio->pin_table[0]); active_value = FIELD_GET(INT3472_GPIO_DSM_SENSOR_ON_VAL, obj->integer.value); if (!active_value) -- 2.51.0 From 6718d42b6eb28228a554db6c8973693ad5320006 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 9 Dec 2024 23:05:21 +0100 Subject: [PATCH 14/16] platform/x86: int3472: Fix skl_int3472_handle_gpio_resources() return value MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The INT3472 code never wants a copy of the ACPI resource to be added to the list-head passed to acpi_dev_get_resources(). Make skl_int3472_handle_gpio_resources() always return -errno or 1. Also update the inaccurate comment about the return value. skl_int3472_handle_gpio_resources() was already returning 1 in the case of not a GPIO resource or invalid _DSM return and not -EINVAL / -ENODEV as the comment claimed. Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20241209220522.25288-3-hdegoede@redhat.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/intel/int3472/discrete.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c index 6e2b81da2d68..31015ebe20d8 100644 --- a/drivers/platform/x86/intel/int3472/discrete.c +++ b/drivers/platform/x86/intel/int3472/discrete.c @@ -178,11 +178,11 @@ static void int3472_get_func_and_polarity(u8 type, const char **func, u32 *polar * to create clocks and regulators via the usual frameworks. * * Return: - * * 1 - To continue the loop - * * 0 - When all resources found are handled properly. - * * -EINVAL - If the resource is not a GPIO IO resource - * * -ENODEV - If the resource has no corresponding _DSM entry - * * -Other - Errors propagated from one of the sub-functions. + * * 1 - Continue the loop without adding a copy of the resource to + * * the list passed to acpi_dev_get_resources() + * * 0 - Continue the loop after adding a copy of the resource to + * * the list passed to acpi_dev_get_resources() + * * -errno - Error, break loop */ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares, void *data) @@ -289,7 +289,8 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares, if (ret < 0) return dev_err_probe(int3472->dev, ret, err_msg); - return ret; + /* Tell acpi_dev_get_resources() to not make a copy of the resource */ + return 1; } static int skl_int3472_parse_crs(struct int3472_discrete_device *int3472) -- 2.51.0 From cc115abc1f9b55092c11c183ebff9ad921251609 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 9 Dec 2024 23:05:22 +0100 Subject: [PATCH 15/16] platform/x86: int3472: Debug log the sensor name MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Debug log the sensor name to make it easier to figure out which INT3472 device is associated with which sensor. Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20241209220522.25288-4-hdegoede@redhat.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/intel/int3472/common.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/platform/x86/intel/int3472/common.c b/drivers/platform/x86/intel/int3472/common.c index b3a2578e06c1..1638be8fa71e 100644 --- a/drivers/platform/x86/intel/int3472/common.c +++ b/drivers/platform/x86/intel/int3472/common.c @@ -70,6 +70,8 @@ int skl_int3472_get_sensor_adev_and_name(struct device *dev, return -ENODEV; } + dev_dbg(dev, "Sensor name %s\n", acpi_dev_name(sensor)); + *name_ret = devm_kasprintf(dev, GFP_KERNEL, I2C_DEV_NAME_FORMAT, acpi_dev_name(sensor)); if (!*name_ret) -- 2.51.0 From 9741f9aa13f6dc3ff24e1d006b2ced5f460e6b6f Mon Sep 17 00:00:00 2001 From: Armin Wolf Date: Tue, 10 Dec 2024 01:16:53 +0100 Subject: [PATCH 16/16] platform/x86: acer-wmi: Add support for Acer PH14-51 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Add the Acer Predator PT14-51 to acer_quirks to provide support for the turbo button and predator_v4 hwmon interface. Reported-by: Rayan Margham Closes: https://lore.kernel.org/platform-driver-x86/CACzB==6tUsCnr5musVMz-EymjTUCJfNtKzhMFYqMRU_h=kydXA@mail.gmail.com Tested-by: Rayan Margham Signed-off-by: Armin Wolf Reviewed-by: Kurt Borja Link: https://lore.kernel.org/r/20241210001657.3362-2-W_Armin@gmx.de Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/acer-wmi.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index d09baa3d3d90..5cff538ee67f 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -393,6 +393,13 @@ static struct quirk_entry quirk_acer_predator_ph315_53 = { .gpu_fans = 1, }; +static struct quirk_entry quirk_acer_predator_pt14_51 = { + .turbo = 1, + .cpu_fans = 1, + .gpu_fans = 1, + .predator_v4 = 1, +}; + static struct quirk_entry quirk_acer_predator_v4 = { .predator_v4 = 1, }; @@ -600,6 +607,15 @@ static const struct dmi_system_id acer_quirks[] __initconst = { }, .driver_data = &quirk_acer_predator_v4, }, + { + .callback = dmi_matched, + .ident = "Acer Predator PT14-51", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Predator PT14-51"), + }, + .driver_data = &quirk_acer_predator_pt14_51, + }, { .callback = set_force_caps, .ident = "Acer Aspire Switch 10E SW3-016", -- 2.51.0