linux/drivers/acpi/acpica/hwtimer.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Name: hwtimer.c - ACPI Power Management Timer Interface
   4 *
   5 *****************************************************************************/
   6
   7/*
   8 * Copyright (C) 2000 - 2015, Intel Corp.
   9 * All rights reserved.
  10 *
  11 * Redistribution and use in source and binary forms, with or without
  12 * modification, are permitted provided that the following conditions
  13 * are met:
  14 * 1. Redistributions of source code must retain the above copyright
  15 *    notice, this list of conditions, and the following disclaimer,
  16 *    without modification.
  17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18 *    substantially similar to the "NO WARRANTY" disclaimer below
  19 *    ("Disclaimer") and any redistribution must be conditioned upon
  20 *    including a substantially similar Disclaimer requirement for further
  21 *    binary redistribution.
  22 * 3. Neither the names of the above-listed copyright holders nor the names
  23 *    of any contributors may be used to endorse or promote products derived
  24 *    from this software without specific prior written permission.
  25 *
  26 * Alternatively, this software may be distributed under the terms of the
  27 * GNU General Public License ("GPL") version 2 as published by the Free
  28 * Software Foundation.
  29 *
  30 * NO WARRANTY
  31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41 * POSSIBILITY OF SUCH DAMAGES.
  42 */
  43
  44#define EXPORT_ACPI_INTERFACES
  45
  46#include <acpi/acpi.h>
  47#include "accommon.h"
  48
  49#define _COMPONENT          ACPI_HARDWARE
  50ACPI_MODULE_NAME("hwtimer")
  51
  52#if (!ACPI_REDUCED_HARDWARE)    /* Entire module */
  53/******************************************************************************
  54 *
  55 * FUNCTION:    acpi_get_timer_resolution
  56 *
  57 * PARAMETERS:  resolution          - Where the resolution is returned
  58 *
  59 * RETURN:      Status and timer resolution
  60 *
  61 * DESCRIPTION: Obtains resolution of the ACPI PM Timer (24 or 32 bits).
  62 *
  63 ******************************************************************************/
  64acpi_status acpi_get_timer_resolution(u32 * resolution)
  65{
  66        ACPI_FUNCTION_TRACE(acpi_get_timer_resolution);
  67
  68        if (!resolution) {
  69                return_ACPI_STATUS(AE_BAD_PARAMETER);
  70        }
  71
  72        if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) {
  73                *resolution = 24;
  74        } else {
  75                *resolution = 32;
  76        }
  77
  78        return_ACPI_STATUS(AE_OK);
  79}
  80
  81ACPI_EXPORT_SYMBOL(acpi_get_timer_resolution)
  82
  83/******************************************************************************
  84 *
  85 * FUNCTION:    acpi_get_timer
  86 *
  87 * PARAMETERS:  ticks               - Where the timer value is returned
  88 *
  89 * RETURN:      Status and current timer value (ticks)
  90 *
  91 * DESCRIPTION: Obtains current value of ACPI PM Timer (in ticks).
  92 *
  93 ******************************************************************************/
  94acpi_status acpi_get_timer(u32 * ticks)
  95{
  96        acpi_status status;
  97
  98        ACPI_FUNCTION_TRACE(acpi_get_timer);
  99
 100        if (!ticks) {
 101                return_ACPI_STATUS(AE_BAD_PARAMETER);
 102        }
 103
 104        /* ACPI 5.0A: PM Timer is optional */
 105
 106        if (!acpi_gbl_FADT.xpm_timer_block.address) {
 107                return_ACPI_STATUS(AE_SUPPORT);
 108        }
 109
 110        status = acpi_hw_read(ticks, &acpi_gbl_FADT.xpm_timer_block);
 111        return_ACPI_STATUS(status);
 112}
 113
 114ACPI_EXPORT_SYMBOL(acpi_get_timer)
 115
 116/******************************************************************************
 117 *
 118 * FUNCTION:    acpi_get_timer_duration
 119 *
 120 * PARAMETERS:  start_ticks         - Starting timestamp
 121 *              end_ticks           - End timestamp
 122 *              time_elapsed        - Where the elapsed time is returned
 123 *
 124 * RETURN:      Status and time_elapsed
 125 *
 126 * DESCRIPTION: Computes the time elapsed (in microseconds) between two
 127 *              PM Timer time stamps, taking into account the possibility of
 128 *              rollovers, the timer resolution, and timer frequency.
 129 *
 130 *              The PM Timer's clock ticks at roughly 3.6 times per
 131 *              _microsecond_, and its clock continues through Cx state
 132 *              transitions (unlike many CPU timestamp counters) -- making it
 133 *              a versatile and accurate timer.
 134 *
 135 *              Note that this function accommodates only a single timer
 136 *              rollover. Thus for 24-bit timers, this function should only
 137 *              be used for calculating durations less than ~4.6 seconds
 138 *              (~20 minutes for 32-bit timers) -- calculations below:
 139 *
 140 *              2**24 Ticks / 3,600,000 Ticks/Sec = 4.66 sec
 141 *              2**32 Ticks / 3,600,000 Ticks/Sec = 1193 sec or 19.88 minutes
 142 *
 143 ******************************************************************************/
 144acpi_status
 145acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed)
 146{
 147        acpi_status status;
 148        u32 delta_ticks;
 149        u64 quotient;
 150
 151        ACPI_FUNCTION_TRACE(acpi_get_timer_duration);
 152
 153        if (!time_elapsed) {
 154                return_ACPI_STATUS(AE_BAD_PARAMETER);
 155        }
 156
 157        /* ACPI 5.0A: PM Timer is optional */
 158
 159        if (!acpi_gbl_FADT.xpm_timer_block.address) {
 160                return_ACPI_STATUS(AE_SUPPORT);
 161        }
 162
 163        /*
 164         * Compute Tick Delta:
 165         * Handle (max one) timer rollovers on 24-bit versus 32-bit timers.
 166         */
 167        if (start_ticks < end_ticks) {
 168                delta_ticks = end_ticks - start_ticks;
 169        } else if (start_ticks > end_ticks) {
 170                if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) {
 171
 172                        /* 24-bit Timer */
 173
 174                        delta_ticks =
 175                            (((0x00FFFFFF - start_ticks) +
 176                              end_ticks) & 0x00FFFFFF);
 177                } else {
 178                        /* 32-bit Timer */
 179
 180                        delta_ticks = (0xFFFFFFFF - start_ticks) + end_ticks;
 181                }
 182        } else {                /* start_ticks == end_ticks */
 183
 184                *time_elapsed = 0;
 185                return_ACPI_STATUS(AE_OK);
 186        }
 187
 188        /*
 189         * Compute Duration (Requires a 64-bit multiply and divide):
 190         *
 191         * time_elapsed (microseconds) =
 192         *  (delta_ticks * ACPI_USEC_PER_SEC) / ACPI_PM_TIMER_FREQUENCY;
 193         */
 194        status = acpi_ut_short_divide(((u64)delta_ticks) * ACPI_USEC_PER_SEC,
 195                                      ACPI_PM_TIMER_FREQUENCY, &quotient, NULL);
 196
 197        *time_elapsed = (u32) quotient;
 198        return_ACPI_STATUS(status);
 199}
 200
 201ACPI_EXPORT_SYMBOL(acpi_get_timer_duration)
 202#endif                          /* !ACPI_REDUCED_HARDWARE */
 203