mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
platform/x86: x86-android-tablets: Add support for getting i2c_adapter by PCI parent devname()
On the Vexia EDU ATLA 10 tablet, which ships with Android + a custom Linux (guadalinex) using the custom Android kernel the I2C controllers are not enumerated as ACPI devices as they typically are. Instead they are enumerated as PCI devices which do not have ACPI firmware nodes associated with them, so getting the i2c_adapter by the ACPI path of its firmware node does not work. Add support for getting the i2c_adapter by the devname() of its PCI parent instead. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Andy Shevchenko <andy@kernel.org> Link: https://lore.kernel.org/r/20241104200848.58693-3-hdegoede@redhat.com Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
This commit is contained in:
parent
01fbfcb3ac
commit
5b78e809f9
3 changed files with 40 additions and 2 deletions
|
@ -5,7 +5,9 @@
|
|||
|
||||
config X86_ANDROID_TABLETS
|
||||
tristate "X86 Android tablet support"
|
||||
depends on I2C && SPI && SERIAL_DEV_BUS && ACPI && EFI && GPIOLIB && PMIC_OPREGION
|
||||
depends on I2C && SPI && SERIAL_DEV_BUS
|
||||
depends on GPIOLIB && PMIC_OPREGION
|
||||
depends on ACPI && EFI && PCI
|
||||
select NEW_LEDS
|
||||
select LEDS_CLASS
|
||||
help
|
||||
|
|
|
@ -11,11 +11,13 @@
|
|||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/serdev.h>
|
||||
#include <linux/string.h>
|
||||
|
@ -170,6 +172,35 @@ get_i2c_adap_by_handle(const struct x86_i2c_client_info *client_info)
|
|||
return i2c_acpi_find_adapter_by_handle(handle);
|
||||
}
|
||||
|
||||
static __init int match_parent(struct device *dev, const void *data)
|
||||
{
|
||||
return dev->parent == data;
|
||||
}
|
||||
|
||||
static struct i2c_adapter *
|
||||
get_i2c_adap_by_pci_parent(const struct x86_i2c_client_info *client_info)
|
||||
{
|
||||
struct i2c_adapter *adap = NULL;
|
||||
struct device *pdev, *adap_dev;
|
||||
|
||||
pdev = bus_find_device_by_name(&pci_bus_type, NULL, client_info->adapter_path);
|
||||
if (!pdev) {
|
||||
pr_err("Error could not find %s PCI device\n", client_info->adapter_path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
adap_dev = bus_find_device(&i2c_bus_type, NULL, pdev, match_parent);
|
||||
if (adap_dev) {
|
||||
adap = i2c_verify_adapter(adap_dev);
|
||||
if (!adap)
|
||||
put_device(adap_dev);
|
||||
}
|
||||
|
||||
put_device(pdev);
|
||||
|
||||
return adap;
|
||||
}
|
||||
|
||||
static __init int x86_instantiate_i2c_client(const struct x86_dev_info *dev_info,
|
||||
int idx)
|
||||
{
|
||||
|
@ -181,7 +212,11 @@ static __init int x86_instantiate_i2c_client(const struct x86_dev_info *dev_info
|
|||
if (board_info.irq < 0)
|
||||
return board_info.irq;
|
||||
|
||||
adap = get_i2c_adap_by_handle(client_info);
|
||||
if (dev_info->use_pci_devname)
|
||||
adap = get_i2c_adap_by_pci_parent(client_info);
|
||||
else
|
||||
adap = get_i2c_adap_by_handle(client_info);
|
||||
|
||||
if (!adap) {
|
||||
pr_err("error could not get %s adapter\n", client_info->adapter_path);
|
||||
return -ENODEV;
|
||||
|
|
|
@ -91,6 +91,7 @@ struct x86_dev_info {
|
|||
int gpio_button_count;
|
||||
int (*init)(struct device *dev);
|
||||
void (*exit)(void);
|
||||
bool use_pci_devname;
|
||||
};
|
||||
|
||||
int x86_android_tablet_get_gpiod(const char *chip, int pin, const char *con_id,
|
||||
|
|
Loading…
Add table
Reference in a new issue