|
19 | 19 | */
|
20 | 20 |
|
21 | 21 | #include <linux/acpi.h>
|
| 22 | +#include <linux/dmi.h> |
22 | 23 | #include <linux/limits.h>
|
23 | 24 | #include <linux/list.h>
|
24 | 25 | #include <linux/module.h>
|
@@ -723,3 +724,73 @@ void acpi_mipi_crs_csi2_cleanup(void)
|
723 | 724 | list_for_each_entry_safe(csi2, csi2_tmp, &acpi_mipi_crs_csi2_list, entry)
|
724 | 725 | acpi_mipi_del_crs_csi2(csi2);
|
725 | 726 | }
|
| 727 | + |
| 728 | +static const struct dmi_system_id dmi_ignore_port_nodes[] = { |
| 729 | + { |
| 730 | + .matches = { |
| 731 | + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
| 732 | + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "XPS 9315"), |
| 733 | + }, |
| 734 | + }, |
| 735 | + { 0 } |
| 736 | +}; |
| 737 | + |
| 738 | +static const char *strnext(const char *s1, const char *s2) |
| 739 | +{ |
| 740 | + s1 = strstr(s1, s2); |
| 741 | + |
| 742 | + if (!s1) |
| 743 | + return NULL; |
| 744 | + |
| 745 | + return s1 + strlen(s2); |
| 746 | +} |
| 747 | + |
| 748 | +/** |
| 749 | + * acpi_graph_ignore_port - Tell whether a port node should be ignored |
| 750 | + * @handle: The ACPI handle of the node (which may be a port node) |
| 751 | + * |
| 752 | + * Returns true if a port node should be ignored and the data to that should |
| 753 | + * come from other sources instead (Windows ACPI definitions and |
| 754 | + * ipu-bridge). This is currently used to ignore bad port nodes related to IPU6 |
| 755 | + * ("IPU?") and camera sensor devices ("LNK?") in certain Dell systems with |
| 756 | + * Intel VSC. |
| 757 | + */ |
| 758 | +bool acpi_graph_ignore_port(acpi_handle handle) |
| 759 | +{ |
| 760 | + const char *path = NULL, *orig_path; |
| 761 | + static bool dmi_tested, ignore_port; |
| 762 | + |
| 763 | + if (!dmi_tested) { |
| 764 | + ignore_port = dmi_first_match(dmi_ignore_port_nodes); |
| 765 | + dmi_tested = true; |
| 766 | + } |
| 767 | + |
| 768 | + if (!ignore_port) |
| 769 | + return false; |
| 770 | + |
| 771 | + /* Check if the device is either "IPU" or "LNK" (sensor). */ |
| 772 | + orig_path = acpi_handle_path(handle); |
| 773 | + if (!orig_path) |
| 774 | + return false; |
| 775 | + path = strnext(orig_path, "IPU"); |
| 776 | + if (!path) |
| 777 | + path = strnext(orig_path, "LNK"); |
| 778 | + if (!path) |
| 779 | + goto out_free; |
| 780 | + |
| 781 | + if (!(path[0] >= '0' && path[0] <= '9' && path[1] == '.')) |
| 782 | + goto out_free; |
| 783 | + |
| 784 | + /* Check if the node has a "PRT" prefix. */ |
| 785 | + path = strnext(path, "PRT"); |
| 786 | + if (path && path[0] >= '0' && path[0] <= '9' && !path[1]) { |
| 787 | + acpi_handle_debug(handle, "ignoring data node\n"); |
| 788 | + |
| 789 | + kfree(orig_path); |
| 790 | + return true; |
| 791 | + } |
| 792 | + |
| 793 | +out_free: |
| 794 | + kfree(orig_path); |
| 795 | + return false; |
| 796 | +} |
0 commit comments