mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 21:38:32 +08:00
Merge branches 'acpi-x86', 'acpi-bus', 'acpi-ec' and 'acpi-apei'
Merge ACPI x86-specific changes, core updates, EC driver updates and APEI support updates for 4.19. These add a special platform driver for handling multiple I2C devices hooked up to the same device object in the ACPI tables, add some new quirks and remove one that is not needed any more. * acpi-x86: platform/x86: Add ACPI i2c-multi-instantiate pseudo driver ACPI / x86: utils: Remove status workaround from acpi_device_always_present() ACPI / x86: enable touchscreen on Dell Venue Pro 7139 * acpi-bus: ACPI: bus: Fix a pointer coding style issue Revert "ACPI / bus: Parse tables as term_list for Dell XPS 9570 and Precision M5530" * acpi-ec: ACPI / EC: Add another entry for Thinkpad X1 Carbon 6th ACPI / EC: Use ec_no_wakeup on ThinkPad X1 Yoga 3rd * acpi-apei: arm64 / ACPI: clean the additional checks before calling ghes_notify_sea()
This commit is contained in:
commit
3c94280456
@ -367,6 +367,12 @@ L: linux-acpi@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/acpi/arm64
|
||||
|
||||
ACPI I2C MULTI INSTANTIATE DRIVER
|
||||
M: Hans de Goede <hdegoede@redhat.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/platform/x86/i2c-multi-instantiate.c
|
||||
|
||||
ACPI PMIC DRIVERS
|
||||
M: "Rafael J. Wysocki" <rjw@rjwysocki.net>
|
||||
M: Len Brown <lenb@kernel.org>
|
||||
|
@ -727,12 +727,7 @@ static const struct fault_info fault_info[] = {
|
||||
|
||||
int handle_guest_sea(phys_addr_t addr, unsigned int esr)
|
||||
{
|
||||
int ret = -ENOENT;
|
||||
|
||||
if (IS_ENABLED(CONFIG_ACPI_APEI_SEA))
|
||||
ret = ghes_notify_sea();
|
||||
|
||||
return ret;
|
||||
return ghes_notify_sea();
|
||||
}
|
||||
|
||||
asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
|
||||
|
@ -66,37 +66,10 @@ static int set_copy_dsdt(const struct dmi_system_id *id)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
static int set_gbl_term_list(const struct dmi_system_id *id)
|
||||
{
|
||||
acpi_gbl_execute_tables_as_methods = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dmi_system_id acpi_quirks_dmi_table[] __initconst = {
|
||||
/*
|
||||
* Touchpad on Dell XPS 9570/Precision M5530 doesn't work under I2C
|
||||
* mode.
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=198515
|
||||
*/
|
||||
{
|
||||
.callback = set_gbl_term_list,
|
||||
.ident = "Dell Precision M5530",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Precision M5530"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = set_gbl_term_list,
|
||||
.ident = "Dell XPS 15 9570",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "XPS 15 9570"),
|
||||
},
|
||||
},
|
||||
static const struct dmi_system_id dsdt_dmi_table[] __initconst = {
|
||||
/*
|
||||
* Invoke DSDT corruption work-around on all Toshiba Satellite.
|
||||
* DSDT will be copied to memory.
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=14679
|
||||
*/
|
||||
{
|
||||
@ -110,7 +83,7 @@ static const struct dmi_system_id acpi_quirks_dmi_table[] __initconst = {
|
||||
{}
|
||||
};
|
||||
#else
|
||||
static const struct dmi_system_id acpi_quirks_dmi_table[] __initconst = {
|
||||
static const struct dmi_system_id dsdt_dmi_table[] __initconst = {
|
||||
{}
|
||||
};
|
||||
#endif
|
||||
@ -962,7 +935,7 @@ static int acpi_device_probe(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_device_remove(struct device * dev)
|
||||
static int acpi_device_remove(struct device *dev)
|
||||
{
|
||||
struct acpi_device *acpi_dev = to_acpi_device(dev);
|
||||
struct acpi_driver *acpi_drv = acpi_dev->driver;
|
||||
@ -1060,8 +1033,11 @@ void __init acpi_early_init(void)
|
||||
|
||||
acpi_permanent_mmap = true;
|
||||
|
||||
/* Check machine-specific quirks */
|
||||
dmi_check_system(acpi_quirks_dmi_table);
|
||||
/*
|
||||
* If the machine falls into the DMI check table,
|
||||
* DSDT will be copied to memory
|
||||
*/
|
||||
dmi_check_system(dsdt_dmi_table);
|
||||
|
||||
status = acpi_reallocate_root_table();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
|
@ -2045,6 +2045,20 @@ static const struct dmi_system_id acpi_ec_no_wakeup[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_FAMILY, "Thinkpad X1 Carbon 6th"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "ThinkPad X1 Carbon 6th",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Carbon 6th"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "ThinkPad X1 Yoga 3rd",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Yoga 3rd"),
|
||||
},
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
|
@ -62,14 +62,20 @@ static const struct always_present_id always_present_ids[] = {
|
||||
*/
|
||||
ENTRY("INT0002", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), {}),
|
||||
/*
|
||||
* On the Dell Venue 11 Pro 7130 the DSDT hides the touchscreen ACPI
|
||||
* device until a certain time after _SB.PCI0.GFX0.LCD.LCD1._ON gets
|
||||
* called has passed *and* _STA has been called at least 3 times since.
|
||||
* On the Dell Venue 11 Pro 7130 and 7139, the DSDT hides
|
||||
* the touchscreen ACPI device until a certain time
|
||||
* after _SB.PCI0.GFX0.LCD.LCD1._ON gets called has passed
|
||||
* *and* _STA has been called at least 3 times since.
|
||||
*/
|
||||
ENTRY("SYNA7500", "1", ICPU(INTEL_FAM6_HASWELL_ULT), {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7130"),
|
||||
}),
|
||||
ENTRY("SYNA7500", "1", ICPU(INTEL_FAM6_HASWELL_ULT), {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7139"),
|
||||
}),
|
||||
|
||||
/*
|
||||
* The GPD win BIOS dated 20170221 has disabled the accelerometer, the
|
||||
* drivers sometimes cause crashes under Windows and this is how the
|
||||
@ -103,13 +109,9 @@ static const struct always_present_id always_present_ids[] = {
|
||||
|
||||
bool acpi_device_always_present(struct acpi_device *adev)
|
||||
{
|
||||
u32 *status = (u32 *)&adev->status;
|
||||
u32 old_status = *status;
|
||||
bool ret = false;
|
||||
unsigned int i;
|
||||
|
||||
/* acpi_match_device_ids checks status, so set it to default */
|
||||
*status = ACPI_STA_DEFAULT;
|
||||
for (i = 0; i < ARRAY_SIZE(always_present_ids); i++) {
|
||||
if (acpi_match_device_ids(adev, always_present_ids[i].hid))
|
||||
continue;
|
||||
@ -125,15 +127,9 @@ bool acpi_device_always_present(struct acpi_device *adev)
|
||||
!dmi_check_system(always_present_ids[i].dmi_ids))
|
||||
continue;
|
||||
|
||||
if (old_status != ACPI_STA_DEFAULT) /* Log only once */
|
||||
dev_info(&adev->dev,
|
||||
"Device [%s] is in always present list\n",
|
||||
adev->pnp.bus_id);
|
||||
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
*status = old_status;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1218,6 +1218,17 @@ config INTEL_CHTDC_TI_PWRBTN
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called intel_chtdc_ti_pwrbtn.
|
||||
|
||||
config I2C_MULTI_INSTANTIATE
|
||||
tristate "I2C multi instantiate pseudo device driver"
|
||||
depends on I2C && ACPI
|
||||
help
|
||||
Some ACPI-based systems list multiple i2c-devices in a single ACPI
|
||||
firmware-node. This driver will instantiate separate i2c-clients
|
||||
for each device in the firmware-node.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called i2c-multi-instantiate.
|
||||
|
||||
endif # X86_PLATFORM_DEVICES
|
||||
|
||||
config PMC_ATOM
|
||||
|
@ -91,3 +91,4 @@ obj-$(CONFIG_PMC_ATOM) += pmc_atom.o
|
||||
obj-$(CONFIG_MLX_PLATFORM) += mlx-platform.o
|
||||
obj-$(CONFIG_INTEL_TURBO_MAX_3) += intel_turbo_max_3.o
|
||||
obj-$(CONFIG_INTEL_CHTDC_TI_PWRBTN) += intel_chtdc_ti_pwrbtn.o
|
||||
obj-$(CONFIG_I2C_MULTI_INSTANTIATE) += i2c-multi-instantiate.o
|
||||
|
132
drivers/platform/x86/i2c-multi-instantiate.c
Normal file
132
drivers/platform/x86/i2c-multi-instantiate.c
Normal file
@ -0,0 +1,132 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* I2C multi-instantiate driver, pseudo driver to instantiate multiple
|
||||
* i2c-clients from a single fwnode.
|
||||
*
|
||||
* Copyright 2018 Hans de Goede <hdegoede@redhat.com>
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
struct i2c_inst_data {
|
||||
const char *type;
|
||||
int gpio_irq_idx;
|
||||
};
|
||||
|
||||
struct i2c_multi_inst_data {
|
||||
int num_clients;
|
||||
struct i2c_client *clients[0];
|
||||
};
|
||||
|
||||
static int i2c_multi_inst_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_multi_inst_data *multi;
|
||||
const struct acpi_device_id *match;
|
||||
const struct i2c_inst_data *inst_data;
|
||||
struct i2c_board_info board_info = {};
|
||||
struct device *dev = &pdev->dev;
|
||||
struct acpi_device *adev;
|
||||
char name[32];
|
||||
int i, ret;
|
||||
|
||||
match = acpi_match_device(dev->driver->acpi_match_table, dev);
|
||||
if (!match) {
|
||||
dev_err(dev, "Error ACPI match data is missing\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
inst_data = (const struct i2c_inst_data *)match->driver_data;
|
||||
|
||||
adev = ACPI_COMPANION(dev);
|
||||
|
||||
/* Count number of clients to instantiate */
|
||||
for (i = 0; inst_data[i].type; i++) {}
|
||||
|
||||
multi = devm_kmalloc(dev,
|
||||
offsetof(struct i2c_multi_inst_data, clients[i]),
|
||||
GFP_KERNEL);
|
||||
if (!multi)
|
||||
return -ENOMEM;
|
||||
|
||||
multi->num_clients = i;
|
||||
|
||||
for (i = 0; i < multi->num_clients; i++) {
|
||||
memset(&board_info, 0, sizeof(board_info));
|
||||
strlcpy(board_info.type, inst_data[i].type, I2C_NAME_SIZE);
|
||||
snprintf(name, sizeof(name), "%s-%s", match->id,
|
||||
inst_data[i].type);
|
||||
board_info.dev_name = name;
|
||||
board_info.irq = 0;
|
||||
if (inst_data[i].gpio_irq_idx != -1) {
|
||||
ret = acpi_dev_gpio_irq_get(adev,
|
||||
inst_data[i].gpio_irq_idx);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Error requesting irq at index %d: %d\n",
|
||||
inst_data[i].gpio_irq_idx, ret);
|
||||
goto error;
|
||||
}
|
||||
board_info.irq = ret;
|
||||
}
|
||||
multi->clients[i] = i2c_acpi_new_device(dev, i, &board_info);
|
||||
if (!multi->clients[i]) {
|
||||
dev_err(dev, "Error creating i2c-client, idx %d\n", i);
|
||||
ret = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, multi);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
while (--i >= 0)
|
||||
i2c_unregister_device(multi->clients[i]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int i2c_multi_inst_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_multi_inst_data *multi = platform_get_drvdata(pdev);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < multi->num_clients; i++)
|
||||
i2c_unregister_device(multi->clients[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_inst_data bsg1160_data[] = {
|
||||
{ "bmc150_accel", 0 },
|
||||
{ "bmc150_magn", -1 },
|
||||
{ "bmg160", -1 },
|
||||
{}
|
||||
};
|
||||
|
||||
/*
|
||||
* Note new device-ids must also be added to i2c_multi_instantiate_ids in
|
||||
* drivers/acpi/scan.c: acpi_device_enumeration_by_parent().
|
||||
*/
|
||||
static const struct acpi_device_id i2c_multi_inst_acpi_ids[] = {
|
||||
{ "BSG1160", (unsigned long)bsg1160_data },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, i2c_multi_inst_acpi_ids);
|
||||
|
||||
static struct platform_driver i2c_multi_inst_driver = {
|
||||
.driver = {
|
||||
.name = "I2C multi instantiate pseudo device driver",
|
||||
.acpi_match_table = ACPI_PTR(i2c_multi_inst_acpi_ids),
|
||||
},
|
||||
.probe = i2c_multi_inst_probe,
|
||||
.remove = i2c_multi_inst_remove,
|
||||
};
|
||||
module_platform_driver(i2c_multi_inst_driver);
|
||||
|
||||
MODULE_DESCRIPTION("I2C multi instantiate pseudo device driver");
|
||||
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
|
||||
MODULE_LICENSE("GPL");
|
@ -118,6 +118,10 @@ static inline void *acpi_hest_get_next(struct acpi_hest_generic_data *gdata)
|
||||
(void *)section - (void *)(estatus + 1) < estatus->data_length; \
|
||||
section = acpi_hest_get_next(section))
|
||||
|
||||
#ifdef CONFIG_ACPI_APEI_SEA
|
||||
int ghes_notify_sea(void);
|
||||
#else
|
||||
static inline int ghes_notify_sea(void) { return -ENOENT; }
|
||||
#endif
|
||||
|
||||
#endif /* GHES_H */
|
||||
|
Loading…
Reference in New Issue
Block a user