Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ACPI / property: Refine consistency check for PRP0001

Refine the check for the presence of the "compatible" property
if the PRP0001 device ID is present in the device's list of
ACPI/PNP IDs to also print the message if _DSD is missing
entirely or the format of it is incorrect.

One special case to take into accout is that the "compatible"
property need not be provided for devices having the PRP0001
device ID in their lists of ACPI/PNP IDs if they are ancestors
of PRP0001 devices with the "compatible" property present.
This is to cover heriarchies of device objects where the kernel
is only supposed to use a struct device representation for the
topmost one and the others represent, for example, functional
blocks of a composite device.

While at it, reduce the log level of the message to "info"
and reduce the log level of the "broken _DSD" message to
"debug" (noise reduction).

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>

+43 -34
+41 -33
drivers/acpi/property.c
··· 79 79 static void acpi_init_of_compatible(struct acpi_device *adev) 80 80 { 81 81 const union acpi_object *of_compatible; 82 - struct acpi_hardware_id *hwid; 83 - bool acpi_of = false; 84 82 int ret; 85 83 84 + ret = acpi_dev_get_property_array(adev, "compatible", ACPI_TYPE_STRING, 85 + &of_compatible); 86 + if (ret) { 87 + ret = acpi_dev_get_property(adev, "compatible", 88 + ACPI_TYPE_STRING, &of_compatible); 89 + if (ret) { 90 + if (adev->parent 91 + && adev->parent->flags.of_compatible_ok) 92 + goto out; 93 + 94 + return; 95 + } 96 + } 97 + adev->data.of_compatible = of_compatible; 98 + 99 + out: 100 + adev->flags.of_compatible_ok = 1; 101 + } 102 + 103 + void acpi_init_properties(struct acpi_device *adev) 104 + { 105 + struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; 106 + bool acpi_of = false; 107 + struct acpi_hardware_id *hwid; 108 + const union acpi_object *desc; 109 + acpi_status status; 110 + int i; 111 + 86 112 /* 87 - * Check if the special PRP0001 ACPI ID is present and in that 88 - * case we fill in Device Tree compatible properties for this 89 - * device. 113 + * Check if the special PRP0001 ACPI ID is present and in that case we 114 + * fill in Device Tree compatible properties for this device. 90 115 */ 91 116 list_for_each_entry(hwid, &adev->pnp.ids, list) { 92 117 if (!strcmp(hwid->id, "PRP0001")) { ··· 120 95 } 121 96 } 122 97 123 - if (!acpi_of) 124 - return; 125 - 126 - ret = acpi_dev_get_property_array(adev, "compatible", ACPI_TYPE_STRING, 127 - &of_compatible); 128 - if (ret) { 129 - ret = acpi_dev_get_property(adev, "compatible", 130 - ACPI_TYPE_STRING, &of_compatible); 131 - if (ret) { 132 - acpi_handle_warn(adev->handle, 133 - "PRP0001 requires compatible property\n"); 134 - return; 135 - } 136 - } 137 - adev->data.of_compatible = of_compatible; 138 - } 139 - 140 - void acpi_init_properties(struct acpi_device *adev) 141 - { 142 - struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; 143 - const union acpi_object *desc; 144 - acpi_status status; 145 - int i; 146 - 147 98 status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf, 148 99 ACPI_TYPE_PACKAGE); 149 100 if (ACPI_FAILURE(status)) 150 - return; 101 + goto out; 151 102 152 103 desc = buf.pointer; 153 104 if (desc->package.count % 2) ··· 157 156 adev->data.pointer = buf.pointer; 158 157 adev->data.properties = properties; 159 158 160 - acpi_init_of_compatible(adev); 161 - return; 159 + if (acpi_of) 160 + acpi_init_of_compatible(adev); 161 + 162 + goto out; 162 163 } 163 164 164 165 fail: 165 - dev_warn(&adev->dev, "Returned _DSD data is not valid, skipping\n"); 166 + dev_dbg(&adev->dev, "Returned _DSD data is not valid, skipping\n"); 166 167 ACPI_FREE(buf.pointer); 168 + 169 + out: 170 + if (acpi_of && !adev->flags.of_compatible_ok) 171 + acpi_handle_info(adev->handle, 172 + "PRP0001 requires 'compatible' property\n"); 167 173 } 168 174 169 175 void acpi_free_properties(struct acpi_device *adev)
+2 -1
include/acpi/acpi_bus.h
··· 208 208 u32 visited:1; 209 209 u32 hotplug_notify:1; 210 210 u32 is_dock_station:1; 211 - u32 reserved:23; 211 + u32 of_compatible_ok:1; 212 + u32 reserved:22; 212 213 }; 213 214 214 215 /* File System */