Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8f275615 authored by Jung-uk Kim's avatar Jung-uk Kim Committed by Rafael J. Wysocki
Browse files

ACPICA: Fix an off-by-one error in acpi_get_timer_duration().

ACPICA commit b4fd33f3c2af014aeec978d46392d286fd7f52b3

Delta calculation has an off-by-one error when there is a rollover.
For example, when start_ticks is 0x00FFFFFF and end_ticks is 0x00000000
(for 24-bit timer), delta_ticks should be 1 (one) but it was 0 (zero).

Link: https://github.com/acpica/acpica/commit/b4fd33f3


Signed-off-by: default avatarJung-uk Kim <jkim@free_BSD.org>
Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarErik Schmauss <erik.schmauss@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 4fbd8d19
Loading
Loading
Loading
Loading
+14 −15
Original line number Diff line number Diff line
@@ -153,7 +153,7 @@ acpi_status
acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 *time_elapsed)
{
	acpi_status status;
	u32 delta_ticks;
	u64 delta_ticks;
	u64 quotient;

	ACPI_FUNCTION_TRACE(acpi_get_timer_duration);
@@ -168,30 +168,29 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed)
		return_ACPI_STATUS(AE_SUPPORT);
	}

	if (start_ticks == end_ticks) {
		*time_elapsed = 0;
		return_ACPI_STATUS(AE_OK);
	}

	/*
	 * Compute Tick Delta:
	 * Handle (max one) timer rollovers on 24-bit versus 32-bit timers.
	 */
	if (start_ticks < end_ticks) {
		delta_ticks = end_ticks - start_ticks;
	} else if (start_ticks > end_ticks) {
	delta_ticks = end_ticks;
	if (start_ticks > end_ticks) {
		if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) {

			/* 24-bit Timer */

			delta_ticks =
			    (((0x00FFFFFF - start_ticks) +
			      end_ticks) & 0x00FFFFFF);
			delta_ticks |= (u64)1 << 24;
		} else {
			/* 32-bit Timer */

			delta_ticks = (0xFFFFFFFF - start_ticks) + end_ticks;
			delta_ticks |= (u64)1 << 32;
		}
	} else {		/* start_ticks == end_ticks */

		*time_elapsed = 0;
		return_ACPI_STATUS(AE_OK);
	}
	delta_ticks -= start_ticks;

	/*
	 * Compute Duration (Requires a 64-bit multiply and divide):
@@ -199,7 +198,7 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed)
	 * time_elapsed (microseconds) =
	 *  (delta_ticks * ACPI_USEC_PER_SEC) / ACPI_PM_TIMER_FREQUENCY;
	 */
	status = acpi_ut_short_divide(((u64)delta_ticks) * ACPI_USEC_PER_SEC,
	status = acpi_ut_short_divide(delta_ticks * ACPI_USEC_PER_SEC,
				      ACPI_PM_TIMER_FREQUENCY, &quotient, NULL);

	*time_elapsed = (u32)quotient;