diff options
-rw-r--r-- | drivers/acpi/internal.h | 1 | ||||
-rw-r--r-- | drivers/acpi/mipi-disco-img.c | 71 | ||||
-rw-r--r-- | drivers/acpi/nfit/core.c | 5 | ||||
-rw-r--r-- | drivers/acpi/processor_idle.c | 2 | ||||
-rw-r--r-- | drivers/acpi/property.c | 3 | ||||
-rw-r--r-- | drivers/acpi/thermal_lib.c | 8 | ||||
-rw-r--r-- | drivers/acpi/utils.c | 2 | ||||
-rw-r--r-- | include/linux/acpi.h | 1 |
8 files changed, 85 insertions, 8 deletions
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 895aa2c0ad58..ca72a0dc5715 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -302,5 +302,6 @@ void acpi_mipi_check_crs_csi2(acpi_handle handle); void acpi_mipi_scan_crs_csi2(void); void acpi_mipi_init_crs_csi2_swnodes(void); void acpi_mipi_crs_csi2_cleanup(void); +bool acpi_graph_ignore_port(acpi_handle handle); #endif /* _ACPI_INTERNAL_H_ */ diff --git a/drivers/acpi/mipi-disco-img.c b/drivers/acpi/mipi-disco-img.c index 7286cf4579bc..d05413a0672a 100644 --- a/drivers/acpi/mipi-disco-img.c +++ b/drivers/acpi/mipi-disco-img.c @@ -19,6 +19,7 @@ */ #include <linux/acpi.h> +#include <linux/dmi.h> #include <linux/limits.h> #include <linux/list.h> #include <linux/module.h> @@ -723,3 +724,73 @@ void acpi_mipi_crs_csi2_cleanup(void) list_for_each_entry_safe(csi2, csi2_tmp, &acpi_mipi_crs_csi2_list, entry) acpi_mipi_del_crs_csi2(csi2); } + +static const struct dmi_system_id dmi_ignore_port_nodes[] = { + { + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "XPS 9315"), + }, + }, + { } +}; + +static const char *strnext(const char *s1, const char *s2) +{ + s1 = strstr(s1, s2); + + if (!s1) + return NULL; + + return s1 + strlen(s2); +} + +/** + * acpi_graph_ignore_port - Tell whether a port node should be ignored + * @handle: The ACPI handle of the node (which may be a port node) + * + * Return: true if a port node should be ignored and the data to that should + * come from other sources instead (Windows ACPI definitions and + * ipu-bridge). This is currently used to ignore bad port nodes related to IPU6 + * ("IPU?") and camera sensor devices ("LNK?") in certain Dell systems with + * Intel VSC. + */ +bool acpi_graph_ignore_port(acpi_handle handle) +{ + const char *path = NULL, *orig_path; + static bool dmi_tested, ignore_port; + + if (!dmi_tested) { + ignore_port = dmi_first_match(dmi_ignore_port_nodes); + dmi_tested = true; + } + + if (!ignore_port) + return false; + + /* Check if the device is either "IPU" or "LNK" (sensor). */ + orig_path = acpi_handle_path(handle); + if (!orig_path) + return false; + path = strnext(orig_path, "IPU"); + if (!path) + path = strnext(orig_path, "LNK"); + if (!path) + goto out_free; + + if (!(isdigit(path[0]) && path[1] == '.')) + goto out_free; + + /* Check if the node has a "PRT" prefix. */ + path = strnext(path, "PRT"); + if (path && isdigit(path[0]) && !path[1]) { + acpi_handle_debug(handle, "ignoring data node\n"); + + kfree(orig_path); + return true; + } + +out_free: + kfree(orig_path); + return false; +} diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index 802f8a56d1fa..d4595d1985b1 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c @@ -1737,9 +1737,8 @@ __weak void nfit_intel_shutdown_status(struct nfit_mem *nfit_mem) if ((nfit_mem->dsm_mask & (1 << func)) == 0) return; - out_obj = acpi_evaluate_dsm(handle, guid, revid, func, &in_obj); - if (!out_obj || out_obj->type != ACPI_TYPE_BUFFER - || out_obj->buffer.length < sizeof(smart)) { + out_obj = acpi_evaluate_dsm_typed(handle, guid, revid, func, &in_obj, ACPI_TYPE_BUFFER); + if (!out_obj || out_obj->buffer.length < sizeof(smart)) { dev_dbg(dev->parent, "%s: failed to retrieve initial health\n", dev_name(dev)); ACPI_FREE(out_obj); diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 55437f5e0c3a..bd6a7857ce05 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -1430,6 +1430,8 @@ int acpi_processor_power_exit(struct acpi_processor *pr) acpi_processor_registered--; if (acpi_processor_registered == 0) cpuidle_unregister_driver(&acpi_idle_driver); + + kfree(dev); } pr->flags.power_setup_done = 0; diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index a6ead5204046..2b73580c9f36 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -80,6 +80,9 @@ static bool acpi_nondev_subnode_extract(union acpi_object *desc, struct acpi_data_node *dn; bool result; + if (acpi_graph_ignore_port(handle)) + return false; + dn = kzalloc(sizeof(*dn), GFP_KERNEL); if (!dn) return false; diff --git a/drivers/acpi/thermal_lib.c b/drivers/acpi/thermal_lib.c index 4e0519ca9739..6214d6ebe1fa 100644 --- a/drivers/acpi/thermal_lib.c +++ b/drivers/acpi/thermal_lib.c @@ -100,7 +100,7 @@ static int thermal_temp(int error, int temp_decik, int *ret_temp) */ int thermal_acpi_active_trip_temp(struct acpi_device *adev, int id, int *ret_temp) { - int temp_decik; + int temp_decik = 0; int ret = acpi_active_trip_temp(adev, id, &temp_decik); return thermal_temp(ret, temp_decik, ret_temp); @@ -119,7 +119,7 @@ EXPORT_SYMBOL_GPL(thermal_acpi_active_trip_temp); */ int thermal_acpi_passive_trip_temp(struct acpi_device *adev, int *ret_temp) { - int temp_decik; + int temp_decik = 0; int ret = acpi_passive_trip_temp(adev, &temp_decik); return thermal_temp(ret, temp_decik, ret_temp); @@ -139,7 +139,7 @@ EXPORT_SYMBOL_GPL(thermal_acpi_passive_trip_temp); */ int thermal_acpi_hot_trip_temp(struct acpi_device *adev, int *ret_temp) { - int temp_decik; + int temp_decik = 0; int ret = acpi_hot_trip_temp(adev, &temp_decik); return thermal_temp(ret, temp_decik, ret_temp); @@ -158,7 +158,7 @@ EXPORT_SYMBOL_GPL(thermal_acpi_hot_trip_temp); */ int thermal_acpi_critical_trip_temp(struct acpi_device *adev, int *ret_temp) { - int temp_decik; + int temp_decik = 0; int ret = acpi_critical_trip_temp(adev, &temp_decik); return thermal_temp(ret, temp_decik, ret_temp); diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index abac5cc25477..202234ba54bd 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -559,7 +559,7 @@ EXPORT_SYMBOL(acpi_evaluate_ost); * * Caller must free the returned buffer */ -static char *acpi_handle_path(acpi_handle handle) +char *acpi_handle_path(acpi_handle handle) { struct acpi_buffer buffer = { .length = ACPI_ALLOCATE_BUFFER, diff --git a/include/linux/acpi.h b/include/linux/acpi.h index b7165e52b3c6..a170c389dd74 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -1170,6 +1170,7 @@ static inline void acpi_ec_set_gpe_wake_mask(u8 action) {} #endif #ifdef CONFIG_ACPI +char *acpi_handle_path(acpi_handle handle); __printf(3, 4) void acpi_handle_printk(const char *level, acpi_handle handle, const char *fmt, ...); |