From: Stanislav Spassov <stanspas@xxxxxxxxx> _DSM Function 9 returns device readiness durations in microseconds. Without this fix, integer truncation could cause msleep()-ing for up to 999us less than actually requested by the firmware. Specifically, if the firmware specifies a 500us delay, msleep(0) would be invoked by the users of the delay values optimized here. Signed-off-by: Stanislav Spassov <stanspas@xxxxxxxxx> --- drivers/pci/pci-acpi.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index a8fa13d6089d..508924377bff 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -1219,6 +1219,11 @@ static void pci_acpi_optimize_delay(struct pci_dev *pdev, acpi_handle handle) { struct pci_host_bridge *bridge = pci_find_host_bridge(pdev->bus); + /* + * _DSM 9 provides values in microseconds, but the kernel uses msleep() + * when waiting, so the code below rounds up when setting value in ms + */ + u64 value_us; int value; union acpi_object *obj, *elements; @@ -1233,12 +1238,18 @@ static void pci_acpi_optimize_delay(struct pci_dev *pdev, if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 5) { elements = obj->package.elements; if (elements[0].type == ACPI_TYPE_INTEGER) { - value = (int)elements[0].integer.value / 1000; + value_us = elements[0].integer.value; + value = (int)(value_us / 1000); + if (value_us % 1000 > 0) + value++; if (value < PCI_PM_D3COLD_WAIT) pdev->d3cold_delay = value; } if (elements[3].type == ACPI_TYPE_INTEGER) { - value = (int)elements[3].integer.value / 1000; + value_us = elements[3].integer.value; + value = (int)(value_us / 1000); + if (value_us % 1000 > 0) + value++; if (value < PCI_PM_D3_WAIT) pdev->d3_delay = value; } -- 2.25.1 Amazon Development Center Germany GmbH Krausenstr. 38 10117 Berlin Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B Sitz: Berlin Ust-ID: DE 289 237 879